我有一个应用程序,其中有两个守卫(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;
}
这是一个插件链接 - http://plnkr.co/edit/EqgruNjogTJvsC1Zt5EN?p=preview
最佳答案
需要理解的非常重要的一点是,在 AuthGuard
中,您进行了一个异步 调用,我们不知道它何时会被解析。其他代码是同步的,将立即执行而无需等待此异步调用(这就是为什么user
未定义
)。
但是您可以强制 AdminGuard
等待,而您的 HTTP 调用将被解析:为此,您可以存储 Observable Subscription(因为您正在使用 observable
,但你也可以用 promise
做同样的事情)到 AuthGuard
的 AuthService
(你在其中创建 HTTP调用)使用以下行:
this.authService.subscription$ = this.http.get('https://jsonplaceholder.typicode.com/users');
现在你的订阅是在AuthService
中,你所需要的只是在两个守卫中订阅
(你正在使用.map()
在你的情况下):
AuthGuard:
return this.authService.subscription$.map(res => {
this.authService.user = {role: 'admin'};
return true;
});
管理 guard :
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!”
- 一切正常。我还从 AuthGuard
和 AdminGuard
中记录了 this.authService.user
变量。
关于javascript - Angular 5(Angular 2+),第二个守卫不等待第一个守卫完成http请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48241851/