Es gibt tatsächlich ein paar damit zusammenhängende Probleme und Möglichkeiten, sie zu beheben.
Lösung 1: Verwenden Sie die mitgelieferte Auth.isLoggedInAsync
Funktion
den AUTH-Modul, ein Teil des erzeugten Codes, ein Verfahren bereit, wenn der Anmeldevorgang abgeschlossen ist zu überprüfen (und eine Rückruffunktion aufzurufen, wenn dies der Fall). Also, eine Möglichkeit, das Problem zu beheben, ist diese Funktion im Client-Code zu verwenden, etwa so:
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;
});
}
};
In diesem Fall werden Sie zwei Anweisungen in der Konsole angezeigt. Der erste wird zeigen, dass Auth.getCurrentUser(). Role noch nicht definiert ist. Der zweite wird zeigen, dass er jetzt einen Wert hat. Wenn Sie also eine Logik haben, die Sie zum Zeitpunkt der Anmeldung ausführen möchten und die von der Benutzerrolle (oder anderen Benutzerattributen) abhängt, legen Sie diese Logik in eine Rückruffunktion, die Sie an Auth.isLoggedInAsync()
übergeben.
Lösung 2: behebt die Ursache in den auth.service.js
Wenn Sie den Code in client/components/auth/auth.service.js
betrachten, werden Sie sehen, dass es ein Problem mit asynchronem Code ist. Das Problem ist, dass currentUser = User.get();
einen asynchronen HTTP-Aufruf auslöst und dass currentUser
nicht sofort festgelegt wird (es ist ein nicht blockierender Aufruf). Da das Versprechen sofort gelöst wird, werden die Kunden davon überzeugt, dass der Anmeldevorgang abgeschlossen ist und alle Benutzerdaten verfügbar sind, während sie tatsächlich noch im Flug sind.
In der vorgeschlagenen Korrektur wird die Zusage in einer Callback-Funktion gelöst, die an User.get()
übergeben wird.
/**
* 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;
},
Verwandte Problem und beheben
Der vorgeschlagene Code behebt ein Problem. Es ist jetzt möglich, den Benutzer bei erfolgreicher Anmeldung auf eine bestimmte Seite umzuleiten. Ein ähnliches Problem tritt jedoch nach dem Anmeldevorgang auf.Auch in diesem Fall ist Auth.getCurrentUser().role
für eine Weile undefiniert (lange genug für die Umleitungslogik fehlgeschlagen).
/**
* 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;
},
Sehr schöne und klare Lösung :) Vielen Dank:
In diesem Fall wurde der Code wie folgt festgesetzt –