我有一个应用程序,其中有两个守卫(AuthGuard - 用于登录用户,AdminGuard - 用于管理员)。第一次加载时的 AuthGuard 会发出 http 请求以从 API 获取用户信息。问题是当您尝试使用两个守卫访问路由时,AdminGuard 不会等待 AuthGuard 完成请求并设置用户,以便 AdminGuard 可以检查用户的 Angular 色,并且应用程序中断。我知道它会中断,因为用户未定义。
我正在寻找如何让第二个守卫等待第一个完成的解决方案。
{
path: 'admin',
component: AdminComponent,
canActivate: [AuthGuard, AdminGuard]
},
@Injectable()
export class AuthGuard implements CanActivate {
constructor(
private authService: AuthService,
private http: HttpClient) { }
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
return this.http.get('https://jsonplaceholder.typicode.com/users').map(res => {
console.log('Auth Guard.');
console.log(res);
this.authService.user = {role: 'admin'};
return true;
});
return false;
}
}
@Injectable()
export class AdminGuard implements CanActivate {
constructor(private authService: AuthService) { }
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
console.log('Admin Guard.');
console.log(this.authService.user);
if (this.authService.user.role === 'admin') {
return true;
}
return false;
}
}
这是一个 plnker 链接 - http://plnkr.co/edit/EqgruNjogTJvsC1Zt5EN?p=preview
最佳答案
需要了解的非常重要的一点是,在 AuthGuard
中,您进行了 异步 调用,但我们不知道它何时会被解决。其他代码是 同步 并且将立即执行而无需等待此异步调用(这就是 user
是 undefined
的原因)。
但是您可以强制 AdminGuard
等待,而您的 HTTP 调用将得到解决:为此,您可以存储 Observable Subscription (因为您正在使用 observable
,但您也可以使用 promise
执行相同的技巧)到 AuthService
从AuthGuard
(您进行 HTTP 调用的地方)使用以下行:
this.authService.subscription$ = this.http.get('https://jsonplaceholder.typicode.com/users');
现在您的订阅位于
AuthService
中,您所需要的只是在两个守卫中对其进行 subscribe
(在您的情况下使用 .map()
):AuthGuard:
return this.authService.subscription$.map(res => {
this.authService.user = {role: 'admin'};
return true;
});
AdminGuard:
return this.authService.subscription$.map(res => {
if (this.authService.user.role === 'admin') {
return true;
}
});
这是工作的plunker:
http://plnkr.co/edit/R2Z26GsSvzEpPdU7tOHO?p=preview
如果您在控制台中看到
"AuthGuard returns TRUE!"
和 "AdminGuard returns TRUE!"
- 一切正常。我还从 this.authService.user
和 AuthGuard
记录了 AdminGuard
变量。关于javascript - Angular 5(Angular 2+),第二个守卫不等待第一个守卫完成http请求,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48241851/