多个 canActivate 守卫在第一次失败时全部运行 [英] Multiple canActivate guards all run when first fails

查看:15
本文介绍了多个 canActivate 守卫在第一次失败时全部运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有两个 canActivate 守卫(AuthGuardRoleGuard)的路线.第一个 (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.如果你只返回一个布尔值,它不会检查 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.

但是,您可以通过仅对需要特定 Role 的 url 使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆