首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >AngularJS -如果用户已登录,则显示/隐藏导航项目

AngularJS -如果用户已登录,则显示/隐藏导航项目
EN

Stack Overflow用户
提问于 2014-11-14 07:12:06
回答 4查看 25K关注 0票数 17

我有一个单页面的AngularJS应用程序,通过Mongoose与Express,node.js和MongoDB一起工作。使用Passport进行用户管理/身份验证。

我希望导航栏项目根据用户是否登录而更改。我在想如何实现它时遇到了麻烦。

我通过http请求找出用户是否已登录:

server.js

代码语言:javascript
复制
app.get('/checklogin',function(req,res){
  if (req.user)
    res.send(true);
  else
    res.send(false);

在前端,我有一个使用Angular的$http服务调用它的NavController

NavController.js

代码语言:javascript
复制
angular.module('NavCtrl',[]).controller('NavController',function($scope,$http) {

    $scope.loggedIn = false;

    $scope.isLoggedIn = function() {

      $http.get('/checklogin')
        .success(function(data) {
          console.log(data);
          if (data === true)
            $scope.loggedIn = true;
          else
            $scope.loggedIn = false;
        })
        .error(function(data) {
          console.log('error: ' + data);
        });
    };
};

在我的导航中,我使用ng-showng-hide来确定哪些选项应该是可见的。我还会在用户单击导航项目时触发isLoggedIn()函数,检查用户在每次单击时是否登录。

index.html

代码语言:javascript
复制
<nav class="navbar navbar-inverse" role="navigation">
  <div class="navbar-header">
    <a class="navbar-brand" href="/">Home</a>
  </div>
  <ul class="nav navbar-nav">
    <li ng-hide="loggedIn" ng-click="isLoggedIn()">
      <a href="/login">Login</a>
    </li>
    <li ng-hide="loggedIn" ng-click="isLoggedIn()">
      <a href="/signup">Sign up</a>
    </li>
    <li ng-show="loggedIn" ng-click="logOut(); isLoggedIn()">
      <a href="#">Log out</a>
    </li>
  </ul>
</nav>

Problem

在我的应用程序中,用户可以在NavController范围之外的其他地方登录/注销。例如,登录页面上有一个对应于LoginController的登录按钮。我想有一个更好的方法来在我的整个应用程序中实现这一点。

如何在后端‘查看’req.user true 是否为,并让我的导航项目做出相应的响应?

EN

回答 4

Stack Overflow用户

发布于 2014-11-14 07:58:31

您可以使用$rootScope在整个应用程序中共享信息:

代码语言:javascript
复制
.controller('NavController',function($scope,$http, $rootScope) {

    $scope.isLoggedIn = function() {

      $http.get('/checklogin')
        .success(function(data) {
          console.log(data);
          $rootScope.loggedIn = data;
        })
        .error(function(data) {
          console.log('error: ' + data);
        });
    };
};

现在,您可以通过访问$rootScope.loggedIn来更改应用程序中其他位置的loggedIn的值,方法与上面的代码相同。

也就是说,您应该将相关代码抽象为服务和指令。这将允许您有一个中心位置来处理、登录、注销和$rootScope.loggedIn的状态。如果你把相关代码的其余部分贴出来,我可以给你一个更具体的答案。

票数 11
EN

Stack Overflow用户

发布于 2014-11-14 07:58:54

您可以在用户成功登录时广播该事件。如果用户已登录,则无需一直轮询您的服务器,您可以在内存中保留一个变量,以告知您是否拥有有效的会话。您可以使用在服务器端设置的基于令牌的身份验证:

代码语言:javascript
复制
services.factory('UserService', ['$resource',                                        
  function($resource){

    // represents guest user - not logged
    var user = {
        firstName : 'guest',
        lastName : 'user',
        preferredCurrency : "USD",
        shoppingCart : {
            totalItems : 0,
            total : 0
        },                                                  
    };

    var resource = function() {
        return $resource('/myapp/rest/user/:id', 
            { id: "@id"}
    )};

    return {
        getResource: function() { 
            return resource;
        },

        getCurrentUser: function() {
            return user;
        },

        setCurrentUser: function(userObj) {
            user = userObj;
        },

        loadUser: function(id) {
            user = resource.get(id);
        }
    }

  }]);

services.factory('AuthService', ['$resource', '$rootScope', '$http', '$location', 'AuthenticationService', 
  function ($resource, $rootScope, $http, $location, AuthenticationService) {
    var authFactory = {
        authData: undefined       
    };

    authFactory.getAuthData = function () {
        return this.authData;
    };

    authFactory.setAuthData = function (authData) {
        this.authData = {
            authId: authData.authId,
            authToken: authData.authToken,
            authPermission: authData.authPermission
        };
        // broadcast the event to all interested listeners
        $rootScope.$broadcast('authChanged');
    };

    authFactory.isAuthenticated = function () {
        return !angular.isUndefined(this.getAuthData());
    };

    authFactory.login = function (user, functionObj) {
        return AuthenticationService.login(user, functionObj);          
    };

    return authFactory;
}]);

services.factory('AuthenticationService', ['$resource',
  function($resource){
    return $resource('/myapp/rest/auth/', 
            {},
            {
              'login': { method: "POST" }
            }               
    );
  }]);          

services.factory('authHttpRequestInterceptor', ['$injector',  
 function ($injector) {
    var authHttpRequestInterceptor = {
        request: function ($request) {
            var authFactory = $injector.get('AuthService');
            if (authFactory.isAuthenticated()) {
                $request.headers['auth-id'] = authFactory.getAuthData().authId;
                $request.headers['auth-token'] = authFactory.getAuthData().authToken;
            }
            return $request;
        }
    };

    return authHttpRequestInterceptor;
}]);

控制器:

代码语言:javascript
复制
controllers.controller('LoginCtrl', ['$scope', '$rootScope', 'AuthService', 'UserService', 
  function LoginCtrl($scope, $rootScope, AuthService, UserService) {
    $scope.login = function () {
        AuthService.login($scope.userInfo, function (data) {
            AuthService.setAuthData(data);
            // set user info on user service to reflect on all UI components
            UserService.setCurrentUser(data.user);
            $location.path('/home/');               
        });
    };

    $scope.isLoggedIn = function () {
        return AuthService.isAuthenticated();
    }

    $scope.user = UserService.getCurrentUser();         
}])
票数 6
EN

Stack Overflow用户

发布于 2014-11-14 08:03:36

您可以使用像EJS这样的模板库在index.html中添加用户的会话数据。

只需添加ejs中间件即可:

代码语言:javascript
复制
var ejs = require('ejs');
// Register ejs as .html.
app.engine('.html', ejs.__express);

然后,当返回index.html时,将会话数据呈现到响应中。

代码语言:javascript
复制
            res.render( "/index.html", {
                session : {
                    user_data : JSON.stringify(req.user)
                }

            });

您现在可以在index.html中访问这些数据,现在您需要将其加载到Angular应用程序中。我使用了preload-resource示例,但您也可以使用自己的方式。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26920217

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档