多个canActivate守护程序在首次失败时全部运行 [英] Multiple canActivate guards all run when first fails
问题描述
我有一条带有两个 canActivate
卫队( AuthGuard
和 RoleGuard
)。第一个( AuthGuard
)检查用户是否已登录,如果没有登录,则重定向到登录页面。第二种方法检查用户是否具有已定义的角色,该角色可以查看该页面,如果没有,则重定向到未经授权的页面。
I have a route with two canActivate
guards (AuthGuard
and RoleGuard
). The first (AuthGuard
) checks to see if the user is logged in and, if not, redirects to the login page. The second checks to see if the user has a role defined that is allowed to view the page and, if not, redirects to the un-authorized page.
canActivate: [ AuthGuard, RoleGuard ]
...
export class AuthGuard implements CanActivate {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
...
this.router.navigate(['/login']);
resolve(false);
}
export class RoleGuard implements CanActivate {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
...
this.router.navigate(['/unauthorized']);
resolve(false);
}
问题是当我访问路线但未登录时点击 AuthGuard
,该操作失败,并告诉路由器导航至 / login
。但是,即使 AuthGuard
失败, RoleGuard
仍会运行,然后导航到 / unauthorized
。
The problem is that when I access the route and I am not logged in I hit the AuthGuard
, which fails and tells the router to navigate to /login
. However, even though the AuthGuard
failed, the RoleGuard
runs anyway which then navigates to /unauthorized
.
在我看来,如果第一个后卫失败,那就去运行下一个后卫是没有意义的。有什么办法可以强制这种行为?
In my opinion it is pointless to run the next guard if the first fails. Is there any way to enforce this behavior?
推荐答案
这是由于您返回的是 Promise< boolean>
,而不只是 boolean
。如果您只返回布尔值,则不会选中 RoleGuard
。我想这可能是 angular2
中的错误,还是异步请求的预期结果。
This is due to the fact you are returning a Promise<boolean>
instead of just a boolean
. If you were to just return a boolean it wouldn't check the RoleGuard
. I would guess this is either a bug in angular2
or an expected result of async requests.
不过,您可以使用示例来解决此问题,只需将 RoleGuard
用于某些角色
是必需的,因为我想您需要先登录才能有角色。在这种情况下,您可以将 RoleGuard
更改为此:
You can however resolve this with your example by only using RoleGuard
for urls where a certain Role
is required, because I guess you need to be logged in to have a role. In that case you can change your RoleGuard
to this:
@Injectable()
export class RoleGuard implements CanActivate {
constructor(private _authGuard: AuthGuard) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
return this._authGuard.canActivate(route, state).then((auth: boolean) => {
if(!auth) {
return false;
}
//... your role guard check code goes here
});
}
}
更新
在最新的Angular版本(当前为v8.x)中-即使两个 Guard 都返回 false
-它们仍将同时执行。 (行为在不同的返回值之间保持一致)
Update
In the latest Angular version (currently v8.x) - Even if both Guard will return false
- they will still be both executed. (behavior was aligned between different return values)
这篇关于多个canActivate守护程序在首次失败时全部运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!