实际上,存在一些相关的问题和解决方法。
Auth模块是生成的代码的一部分,提供了一种方法来检查登录过程是否已完成(在这种情况下,并调用回调函数)。因此,解决此问题的一种方法是在客户端代码中使用此功能,如下所示:
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); Auth.isLoggedInAsync(function(success) {console.log('Current user role: ' + Auth.getCurrentUser().role); }); $location.path(’/’); }) .catch( function(err) { $scope.errors.other = err.message; }); }};
在这种情况下,您将在控制台中看到两个语句。第一个将显示Auth.getCurrentUser()。role仍未定义。第二个将显示它现在具有值。因此,如果您有要在登录时执行的逻辑,并且该逻辑取决于用户角色(或其他用户属性),请将此逻辑放入传递给的回调函数中Auth.isLoggedInAsync()。
如果查看中的代码client/components/auth/auth.service.js,您将看到异步代码存在问题。问题在于,它`currentUserUser.get();会触发一个异步HTTP调用,并且currentUser`不会立即设置(这是一个非阻塞调用)。由于立即兑现了承诺,因此客户被引导相信登录过程已完成,并且所有用户数据均可用,而实际上仍在进行中。
在建议的修复程序中,通过传递给的回调函数解决了promise 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; },解决方法
我们将DaftMonk / AngularJS Full-Stack生成器用于projet。生成的代码包含用于管理用户(注册,登录,角色等)的逻辑,这很棒。但是,使用代码时会出现问题,并且当前用户的角色有时是不确定的。
我们想要实现一个简单的功能时遇到了这个问题:登录/注册后,应该将用户重定向到一个取决于其角色的URL。例如,’teacher’应将用户重定向到/teacherHome,将’student’用户重定向到/studentHome。由于Auth.getCurrentUser()。role未定义,因此逻辑不起作用。
如何重现问题
要重现此问题,请编辑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; }); }};...
测试此代码时,您会发现在此阶段未定义用户角色。但是,稍后会为其分配一个值。这表明该问题可能与异步REST调用有关。