我们遇到了这个问题,因为我们想要实现一个简单的功能:登录/注册后,应该将用户重定向到一个取决于他的角色的URL.例如,“老师”用户应该被重定向到/ teacherHome,“学生”用户应该被重定向到/ studentHome.由于Auth.getCurrentUser().角色未定义,因此逻辑不起作用.
如何重现这个问题
要重现此问题,请编辑client / app / account / login / login.controller.js文件并添加语句以记录Auth.getCurrentUser().role的值,如下所示:
... if(form.$valid) { Auth.login({ email: $scope.user.email,password: $scope.user.password }) .then( function() { // Logged in,redirect to home console.log("Current user role: " + Auth.getCurrentUser().role); $location.path('/'); }) .catch( function(err) { $scope.errors.other = err.message; }); } }; ...
解决方案1:使用提供的Auth.isLoggedInAsync函数
Auth模块是生成代码的一部分,它提供了一种检查登录过程是否已完成的方法(并在这种情况下调用回调函数).因此,解决问题的一种方法是在客户端代码中使用此函数,如下所示:
if(form.$valid) { Auth.login({ email: $scope.user.email,redirect to home console.log("Current user role: " + Auth.getCurrentUser().role); Auth.isLoggedInAsync(function(success) { console.log("Current user role: " + Auth.getCurrentUser().role); }); $location.path('/'); }) .catch( function(err) { $scope.errors.other = err.message; }); } };
在这种情况下,您将在控制台中看到两个语句.第一个将显示Auth.getCurrentUser().角色仍未定义.第二个将显示它现在有一个值.因此,如果您希望在登录时执行逻辑并且这取决于用户角色(或其他用户属性),请将此逻辑放在您传递给Auth.isLoggedInAsync()的回调函数中.
解决方案2:在auth.service.js中修复根本原因
如果查看client / components / auth / auth.service.js中的代码,您将看到异步代码存在问题.问题是currentUser = User.get();触发异步HTTP调用,并且不立即设置currentUser(它是非阻塞调用).由于承诺立即得到解决,客户可以相信登录过程已经完成并且所有用户数据都可用,而实际上它仍处于飞行状态.
在建议的修复中,承诺在传递给User.get()的回调函数中得到解决.
/** * Authenticate user and save token * * @param {Object} user - login info * @param {Function} callback - optional * @return {Promise} */ login: function (user,callback) { var cb = callback || angular.noop; var deferred = $q.defer(); $http.post('/auth/local',{ email: user.email,password: user.password }). /* ORIGINAL CODE -- promise is resolved too early success(function (data) { $cookieStore.put('token',data.token); currentUser = User.get(); deferred.resolve(data); return cb(); }). */ /* PROPOSED FIX -- promise is resolved once HTTP call has returned */ success(function (data) { $cookieStore.put('token',data.token); currentUser = User.get(function() { deferred.resolve(data); return cb(); }); }). error(function (err) { this.logout(); deferred.reject(err); return cb(err); }.bind(this)); return deferred.promise; },
相关问题和修复
建议的代码修复了一个问题.现在可以在成功登录后将用户重定向到特定页面.但是,在注册过程之后会出现类似的问题.在这种情况下,Auth.getCurrentUser().role一段时间内未定义(足够长的时间以使重定向逻辑失败).
在这种情况下,代码修复如下:
/** * Create a new user * * @param {Object} user - user info * @param {Function} callback - optional * @return {Promise} */ createUser: function (user,callback) { var cb = callback || angular.noop; /* ORIGINAL CODE --------------------- return User.save(user,function(data) { $cookieStore.put('token',data.token); currentUser = User.get(); return cb(user); },function(err) { this.logout(); return cb(err); }.bind(this)).$promise; --------------------- */ /* PROPOSED FIX --------------------- */ var deferred = $q.defer(); User.save(user,function (data) { $cookieStore.put('token',data.token); currentUser = User.get(function () { console.log('User.save(),user role: ' + currentUser.role); deferred.resolve(data); return cb(currentUser); }); },function (err) { this.logout(); return cb(err); deferred.reject(err); }); return deferred.promise; },