所以,我真的很接近有这个想通了。基本上,我已经登录的工作和我的代码设置来监视onAuthStateChanged,但问题是,当我刷新页面,即使用户当前已登录,但它仍然重定向到/login
页面,因为AUTH后卫,我有设置,检查是否用户被登录。
我有一个权威性的服务设置,做所有的认证检查。
在我的身份验证服务的构造,这就是我有我的onAuthStateChanged
代码设置:
constructor(
private auth: AngularFireAuth,
private router:Router,
private db:AngularFireDatabase,
) {
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// What do I need to put here to ensure that the auth guard goes to the intended route?
}
});
}
这里是我的身份验证后卫的canActivate()
方法:
canActivate(route:ActivatedRouteSnapshot, state:RouterStateSnapshot):Observable<boolean> {
if(this.authService.getAuthenticated()) {
return Observable.of(true);
} else {
this.router.navigate(['/login']);
}
}
这里是getAuthenticated()
方法:
getAuthenticated() {
return firebase.auth().currentUser;
}
更新:
下面是当用户在实际登录时调用的方法在实际的成分,这里是登录方法:
login(data, isValid) {
if(isValid) {
this.authService.login(data.email, data.password)
.then(
(data) => {
console.log('data', data);
this.router.navigate(['/projects'])
}, error => {
this._utilities.createToasty({
msg: "The email/password combination is incorrect.",
type: "error"
});
}
);
}
}
而在身份验证服务,这里的登录方法:
login(email, password) {
return firebase.auth().signInWithEmailAndPassword(email, password);
}
所以现在,我不能完全肯定我需要把在那里,以确保当我的用户刷新页面中,auth后卫上拿起什么代码,实际上允许用户去的路线,而不是总是重定向到/login
路线。
思考?
我真的不知道答案,因为我不使用火力所以这些都是更多的指针
猜测1:用户处于中间状态
运行在后台的认证功能,当canActivate方法确实还没有运行。因此,当前用户并没有被设定。我想简单的火力去你的本地存储和检查,如果令牌是有效的。如果这是它做什么,然后只需确保这个canActivate之前发生。
但是它可能之前运行,并有当前用户仍然不确定,如果它是异步这是完全可能的。然后,你就必须确保canActivate运行它结算后。
其实,更重要的是:使用可观察到的在你可以激活方法所示:
码:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return this.af.auth.map((auth) => {
if (!auth) {
this.router.navigateByUrl('login');
return false;
}
return true;
}).take(1);
}
猜测二:你必须存储在本地存储的东西。
这些认证服务通常需要存储令牌在本地存储,那么这个令牌用于在页面刷新的用户进行身份验证。什么我可以读这是在与火力后台完成。你仍然可以检查本地存储/会话存储只是要确定你看到的信息的存在。
如果你没有看到的localStorage / sessionStorage的任何相关信息,那么可能是你把在那里的东西在登录时。
我有同样的问题,因为你的,我做了以下与localStorage的解决这个问题:
login(email, password): Observable<AuthInfo> {
return this.fromFirebaseAuthPromise(this.afAuth.auth.signInWithEmailAndPassword(email, password));
}
我只是说localStorage.setItem("user", this.afAuth.auth.currentUser.uid);
到登录响应和localStorage.removeItem("user");
为退出方法。
fromFirebaseAuthPromise(promise): Observable<any> {
const subject = new Subject<any>();
promise
.then(res => {
const authInfo = new AuthInfo(this.afAuth.auth.currentUser.uid);
this.authInfo$.next(authInfo);
subject.next(res);
subject.complete();
localStorage.setItem("user", this.afAuth.auth.currentUser.uid);
},
err => {
this.authInfo$.error(err);
subject.error(err);
subject.complete();
});
return subject.asObservable();
}
logout() {
this.afAuth.auth.signOut();
localStorage.removeItem("user");
this.authInfo$.next(AuthService.UNKNOWN_USER);
this.router.navigate(['/login']);
}
并改变了canActivate()
方法为以下:
canActivate() {
//you can check token is exists or not here
if (localStorage.getItem('user')) {
console.log("user ist logged in ....", localStorage.getItem('user'));
return true;
} else {
console.log("user is not logged in");
this.router.navigate(['/login']);
return false;
}
}
firebase.auth().onAuthStateChanged(function (user) {
console.log('onAuthStateChanged: ', user);
});
让我尝试在本地存储用户数据保存解决这个问题。当用户登录,我们将保存本地存储用户数据,通过这样做,我们将不得不重新加载页面后,即使用户状态我的逻辑是非常简单的。
userData: any;
constructor(
public afAuth: AngularFireAuth
) {
this.afAuth.authState.subscribe(user => {
if (user) {
localStorage.setItem('user', JSON.stringify(this.userData));
JSON.parse(localStorage.getItem('user'));
} else {
localStorage.setItem('user', null);
JSON.parse(localStorage.getItem('user'));
}
})
}
写里面的setTimeout代码。由于清爽页面后,这个问题会发生。
setTimeout(()=>{
console.log("currentUser", firebase.auth().currentUser);
},1000)