无法在角度 6 中检查 AuthGuard 中的 JWT 有效性?

Posted

技术标签:

【中文标题】无法在角度 6 中检查 AuthGuard 中的 JWT 有效性?【英文标题】:Unable to check JWT validity in AuthGuard in angular 6? 【发布时间】:2019-06-28 01:02:53 【问题描述】:

我创建了一个带有简单登录页面和仪表板的 Angular 应用程序。仪表板是一个安全页面,应在有效登录后打开。

在提交按钮上,我正在调用身份验证服务来检查用户凭据的有效性,在响应中,我收到了一个存储在本地存储中的 JWT。

我还创建了一个 AuthGuard 来保护仪表板。在 AuthGuard 中,我无法确定此 JWT 是否有效(任何用户都可以创建一些随机密钥并访问仪表板)。

我是否必须在 Dashboard Init() 方法中创建一些方法来检查 JWT 的有效性,如果是,那么 AuthGuard 的目的是什么?请提出建议。

login.component.ts:

this.authenticationService.login(this.f.userName.value, this.f.password.value)
      .pipe(first())
      .subscribe(
        data => 
          this.router.navigate(['/dashboard']);
        ,
        error => 
          // this.error = error;
          // this.loading = false;
        );

身份验证服务.ts

login(username: string, password: string) 
        return this.http.post<any>('http://localhost:59900/api/login',  username, password )
            .pipe(map(user => 
                // login successful if there's a jwt token in the response&& user.token
                debugger;
                if (user ) 
                    // store user details and jwt token in local storage to keep user logged in between page refreshes
                    localStorage.setItem('currentUser', JSON.stringify(user));
                
                return user;
            ));
    

AuthGuard:

export class AuthGuard implements CanActivate 

    constructor(private router: Router)  

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) 
        debugger;
        if (localStorage.getItem('currentUser')) 
            // logged in so return true
            return true;
        

        // not logged in so redirect to login page with the return url
        this.router.navigate(['/login'],  queryParams:  returnUrl: state.url  );
        return false;
    

【问题讨论】:

是否足以检查 currentUser 是否在本地存储中?任何人都可以在他的 localStorage 中设置 currentUser 并绕过你的 Guard 【参考方案1】:

当您在 localStorage 中保存令牌时,您应该承认用户可以更改它并设置自己的令牌的风险。但我猜你有一些后端服务正在检查访问或刷新令牌的有效性。因此,如果您需要使用警卫验证用户令牌,您可以从警卫向后端发送一些请求,如果用户已通过身份验证(意味着令牌有效),则返回 true。无论如何,如果您通过授权从后端返回一些信息,则任何用户都需要拥有有效的令牌。你会从警卫那里做还是从页面做。 例如,我更喜欢在守卫之外检查令牌有效性。关于控制器初始化 (OnInit)。

请记住,您不得在未经授权的情况下从后端保存或加载受应用程序保护的数据。

关于:我是否必须在 Dashboard Init() 方法中创建一些方法来检查 JWT 的有效性,如果是,那么 AuthGuard 的目的是什么?请提出建议。

一般用户不会手动添加本地存储项,所以只能检查token是否存在。

另外,我使用的是来自 Auth0 的包 angular jwt。 https://github.com/auth0/angular-jwt 使用包我正在检查令牌是否过期。查看我的代码:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot)    
  const refToken = refreshTokenGetter();
  const helper = new JwtHelperService();
  const isExpired = helper.isTokenExpired(refToken);

  if (refToken && !isExpired) 
      return true;
  

  this.router.navigate(['auth']);

【讨论】:

你能解释一下 IsTokenExpired 方法的作用吗?它是在服务器端还是在客户端检查令牌的令牌过期时间? 它在客户端检查令牌过期时间。它使用 JwtHelperService 工作,它是 angular-jwt 包(由 auth0 创建的包)的一部分。我很伤心,您也应该在后端检查 jwt 的有效性,但没有必要从警卫那里进行。在从后向前发送数据之前,您可以在任何地方执行此操作。选择最佳选项,例如性能。

以上是关于无法在角度 6 中检查 AuthGuard 中的 JWT 有效性?的主要内容,如果未能解决你的问题,请参考以下文章

刷新令牌时,AuthGuard 服务 canActivate 无法导航

防止在角度4中在浏览器中重定向写入URL

角度路由可以激活 AuthGuard 传输查询参数

关于 Angular 中的 AuthGuard

无法解析AuthGuard的所有参数:在我的AuthGuard服务中

Angular 2:未处理的承诺拒绝:没有 AuthService 的提供者! ;区域:角度