Upv*_*ote 7 angularfire2 angular2-guards angular
我想要实现的目标:我想使用 BehaviorSubject 在我的应用程序中共享身份验证状态。我使用身份验证状态,例如在 auth-guard 内部,以防止用户在用户已经通过身份验证时访问登录/注册页面。
问题:因为 BehaviorSubject 有一个初始值,它是 false(未登录),似乎 auth-guard 取了这个第一个值,而不是等待 uid-sync。
AuthInfo(身份验证状态存储):
export class AuthInfo {
constructor(public uid: string) {}
isLoggedIn() {
return !!this.uid;
}
}
Run Code Online (Sandbox Code Playgroud)
身份验证服务:
@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});
}
}
Run Code Online (Sandbox Code Playgroud)
身份验证:
@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();
});
}
}
Run Code Online (Sandbox Code Playgroud)
所以canActivate与处理authInfo.isLoggedIn()是false与第二我看到的一小部分后,Got the uid在控制台中。任何想法如何防止第一个false?我认为这里正确使用了 BehaviorSubject,因为它允许我们设置初始状态。然而,auth-guard 总是会收到 false(初始值)。在那之后
this.authInfo$.next(new AuthInfo(auth.uid));
Run Code Online (Sandbox Code Playgroud)
将在 canActivate 方法已经完成时触发。
Guard 的canActivate方法,顾名思义,在尝试激活特定路由时进行解析。
正如我从提供的代码中了解到的,您试图/user在uid从服务器检索身份验证时将用户重定向到路由。为了实现这一点,您需要在uid检索到身份验证后启动重定向到所需的路线- 例如在登录后,让您的守卫完成其工作,启用或拒绝对路线的访问。
整理好之后,这里是经过更改的代码和结构的演练:
AuthInfo 类:
// No changes.
Run Code Online (Sandbox Code Playgroud)
身份验证服务:
@Injectable()
export class AuthService {
static UNKNOWN_USER = new AuthInfo(null);
authInfo$: BehaviorSubject<AuthInfo> = new BehaviorSubject<AuthInfo>(AuthService.UNKNOWN_USER);
constructor(private af: AngularFire) { }
logIn(email: string, password: string): Promise<FirebaseAuthState> {
return this.af.auth.login({email: email, password: password});
}
getAuthInfo(): Observable<AuthInfo> {
return this.af.auth.map(auth => {
if(auth) {
console.log('got the uid');
let authInfo = new AuthInfo(auth.uid);
this.authInfo$.next(authInfo);
return authInfo;
}
else {
this.authInfo$.next(AuthService.UNKNOWN_USER);
return AuthService.UNKNOWN_USER;
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
身份验证:
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService,
private router: Router) {
}
canActivate(): Observable<boolean> | boolean {
// get the most recent value BehaviorSubject holds
if (this.authService.authInfo$.getValue().isLoggedIn()) {
// can access targeted route
return true;
}
/*
User is not logged in as stored authInfo indicates,
but in case the page has been reloaded, the stored value is lost,
and in order to get real auth status we will perform the server call,
(authService.getAuthInfo method will automatically update the BehaviorSubject value,
and next time the protected route is accessed, no additional call will be made - until
the next reloading).
*/
return this.authService.getAuthInfo()
.map((authInfo: AuthInfo) => {
if(authInfo.isLoggedIn()) {
// can access targeted route
return true;
}
this.router.navigate(['login']); // redirect to login screen
return false;
});
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5141 次 |
| 最近记录: |