在控制器AngularJS中使用经过身份验证的用户对象属性

时间:2014-05-09 06:01:07

标签: angularjs mean-stack

我开始使用MEAN Stack利用angular-fullstack生成器。它附带一个Authentication服务,它有一个返回当前用户对象的方法。

我正以这种方式成功从Controller中检索Authenticated User对象:

angular.module('myApp')
   .controller('CompanyOwnerCtrl', function ($scope, $http, Auth) {
       $scope.user = Auth.currentUser();

});

$ scope.user实际上保存了用户对象,因为我能够在视图中显示其所有属性:

{{user}} //prints successfully all user data

我的问题是我无法在控制器中使用_id属性来调用后端并从另一个集合中检索数据

angular.module('myApp')
   .controller('CompanyOwnerCtrl', function ($scope, $http, Auth) {
       var u = Auth.currentUser();
       $scope.user = u;

       //retrieve additional data
       $http.get('/api/companies/' + $scope.user._id) 
         .then(function(result) {
            $scope.company = result.data; 
       }); 

});

如果我尝试上面的代码来检索公司信息,它说$ scope.user._id是未定义但是如果我在我的视图中写入

{{user._id}}

正确显示用户ID。我可能没有使用最好的方法,因为这个项目只是为了学习堆栈,但是,有谁知道为什么我不能像我在控制器中那样使用用户ID?

编辑:这是验证服务

'use strict';

angular.module('myApp')
.factory('Auth', function Auth($location, $rootScope, Session, User, $cookieStore) {

// Get currentUser from cookie
$rootScope.currentUser = $cookieStore.get('user') || null;
$cookieStore.remove('user');

return {

  /**
   * Authenticate user
   * 
   * @param  {Object}   user     - login info
   * @param  {Function} callback - optional
   * @return {Promise}            
   */
  login: function(user, callback) {
    var cb = callback || angular.noop;

    return Session.save({
      email: user.email,
      password: user.password
    }, function(user) {
      $rootScope.currentUser = user;
      return cb();
    }, function(err) {
      return cb(err);
    }).$promise;
  },

  /**
   * Unauthenticate user
   * 
   * @param  {Function} callback - optional
   * @return {Promise}           
   */
  logout: function(callback) {
    var cb = callback || angular.noop;

    return Session.delete(function() {
        $rootScope.currentUser = null;
        return cb();
      },
      function(err) {
        return cb(err);
      }).$promise;
  },

  /**
   * Create a new user
   * 
   * @param  {Object}   user     - user info
   * @param  {Function} callback - optional
   * @return {Promise}            
   */
  createUser: function(user, callback) {
    var cb = callback || angular.noop;

    return User.save(user,
      function(user) {
        $rootScope.currentUser = user;
        return cb(user);
      },
      function(err) {
        return cb(err);
      }).$promise;
  },

  /**
   * Change password
   * 
   * @param  {String}   oldPassword 
   * @param  {String}   newPassword 
   * @param  {Function} callback    - optional
   * @return {Promise}              
   */
  changePassword: function(oldPassword, newPassword, callback) {
    var cb = callback || angular.noop;

    return User.update({
      oldPassword: oldPassword,
      newPassword: newPassword
    }, function(user) {
      return cb(user);
    }, function(err) {
      return cb(err);
    }).$promise;
  },

  /**
   * Gets all available info on authenticated user
   * 
   * @return {Object} user
   */
  currentUser: function() {
    return User.get();
  },


  /**
   * Simple check to see if a user is logged in
   * 
   * @return {Boolean}
   */
  isLoggedIn: function() {
    var user = $rootScope.currentUser;
    return !!user;
  },
};

});

2 个答案:

答案 0 :(得分:2)

这是针对此问题的一种可行且有效的解决方案。请记住,这个特殊的解决方案适用于angular-fullstack生成器,我不知道后端是否有类似的实现用于其他生成器

我没有使用Auth.currentUser()方法,而是最终调用连接到当前用户会话的/ api / users / me端点,因此返回所有当前用户信息。

$http.get('/api/users/me') 
  .then(function(result) {
    $scope.userId = result.data._id;
    // Do whatever you need to do with the userId here.

});

最好在每个页面中调用/ api / users / me,而不是出于安全原因将userId存储在会话中。请记住在路线中添加authenticate:true以确保始终有登录用户。

答案 1 :(得分:1)

我的猜测是,当到达$http调用的代码行时,$scope上的用户对象没有填充,但过了一会儿它就是为什么你可以检查视图中的_id,可能是由于某些异步操作?如何观看用户对象并仅在呼叫存在时进行呼叫?

$scope.$watch(Auth.currentUser,function(user){
       if(user){
          $scope.user=user;
          $scope.GetCompanyDetails(user._id);
       }
},true);

$scope.GetCompanyDetails=function(userId){
       $http.get('/api/companies/' + userId) 
         .then(function(result) {
            $scope.company = result.data; 
       }); 
}