What I want to achieve: 我想使用BehaviorSubject在我的应用程序中共享身份验证状态 . 我使用身份验证状态,例如在auth-guard内部,以防止用户在用户已经过身份验证时访问登录/注册页面 .
Problem: 因为BehaviorSubject有一个初始值,它是假的(未登录),似乎auth-guard取第一个值,而不是等待uid-sync .
AuthInfo(Auth状态存储):
export class AuthInfo {
constructor(public uid: string) {}
isLoggedIn() {
return !!this.uid;
}
}
AuthService:
@Injectable()
export class AuthService {
static UNKNOWN_USER = new AuthInfo(null);
authInfo$: BehaviorSubject<AuthInfo> = new BehaviorSubject<AuthInfo>(AuthService.UNKNOWN_USER);
constructor(private af: AngularFire) {
this.af.auth.subscribe(auth => {
if (auth) {
console.log('got the uid');
this.authInfo$.next(new AuthInfo(auth.uid));
} else {
this.authInfo$.next(AuthService.UNKNOWN_USER);
}
});
}
logIn(email: string, password: string): Promise<FirebaseAuthState> {
return this.af.auth.login({email: email, password: password});
}
}
AuthGuard:
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService,
private router: Router) {
}
canActivate(): Observable<boolean> {
return this.authService.authInfo$.map(authInfo => {
if (authInfo.isLoggedIn()) {
this.router.navigate(['/user'])
}
return !authInfo.isLoggedIn();
});
}
}
所以canActivate用 authInfo.isLoggedIn()
处理 false
并且在一小段时间之后我在控制台中看到 Got the uid
. 任何想法如何防止第一个 false
?我认为这里正确使用BehaviorSubject,因为它允许我们设置初始状态 . 但是,auth-guard将始终收到false(初始值) . 就在那之后
this.authInfo$.next(new AuthInfo(auth.uid));
当canActivate方法已经完成时将触发 .
1 回答
正如其名称所示,Guard的canActivate方法可以解决激活特定路线的问题 .
据我所知,从提供的代码中,您尝试从服务器检索auth
uid
时将用户重定向到/user
路由 . 为了实现这一点,一旦检索到authuid
,你需要启动重定向到所需的路由 - 例如登录后,让您的警卫完成其工作,启用或拒绝访问该路线 .在对事情进行排序之后,这里是改变的代码和结构的演练:
AuthInfo类:
AuthService:
AuthGuard: