【问题标题】:AuthGuard service canActivate doesn't navigate when token refreshed刷新令牌时,AuthGuard 服务 canActivate 无法导航
【发布时间】:2017-11-19 22:58:07
【问题描述】:

AuthGuard 有一个奇怪的问题。

当我单击一个链接时,它会检查用户是否拥有有效的访问令牌。如果没有,它将寻找一个刷新令牌,然后尝试使用它来获取一个访问令牌 (this.oAuthService.refreshToken())。

如果需要刷新,它似乎无法导航。令牌已刷新,但页面无法导航。在令牌刷新发生后,我可以在第二次单击受保护页面的链接后成功导航。

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean>
{
    this.authUserService.lastUrl = state.url;

    if (this.oAuthService.hasValidAccessToken()) {
      this.authUserService.requireLoginSubject.next(false);
      return Observable.of(true);
    } else {

      if (sessionStorage.getItem('refresh_token') === null) {
        this.router.navigateByUrl('/sessiontimeout');
        this.authUserService.requireLoginSubject.next(true);
        return Observable.of(false);
      }

      this.oAuthService.refreshToken().then(() => 
      {
        console.log("refreshed token");
        this.authUserService.requireLoginSubject.next(false);
        return Observable.of(true);
      }).catch(() => {
        this.router.navigateByUrl('/sessiontimeout');
        this.authUserService.requireLoginSubject.next(true);
        return Observable.of(false);
      });
    }
}

【问题讨论】:

  • canActivate 也支持承诺。因此,您可以选择返回Promise.resolve(true)。如果你在某个地方确实有一个 observable,你可以轻松地将它转换为 promise。 myObservable.toPromise()

标签: angular jwt


【解决方案1】:

我想你忘了在刷新案例上添加返回:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean>
{
    this.authUserService.lastUrl = state.url;

    if (this.oAuthService.hasValidAccessToken()) {
      this.authUserService.requireLoginSubject.next(false);
      return Observable.of(true);
    } else {

      if (sessionStorage.getItem('refresh_token') === null) {
        this.router.navigate(['/sessiontimeout']);
        this.authUserService.requireLoginSubject.next(true);
        return Observable.of(false);
      }

      return Observable.fromPromise(this.oAuthService.refreshToken())
             .mergeMap(()=>{
                       this.authUserService.requireLoginSubject.next(false);
                       return Observable.of(true);
              })
             .catch(()=>{
                      this.router.navigateByUrl('/sessiontimeout');
                      this.authUserService.requireLoginSubject.next(true);
                      return Observable.of(false);
              });
}

编辑:将 promise 转换为 Observable,以便更轻松地连接运算符。

【讨论】:

  • refreshToken() 是一个承诺。如果没有编译错误,我无法从这里返回它。
  • 是的,我的错。我不是一个有承诺的专家。我将编辑我的答案,但你能提供更多代码吗?守卫类和 refreshToken 方法会很有帮助
  • refreshToken 方法是否返回一个没有 val 的承诺?
猜你喜欢
  • 2020-04-13
  • 1970-01-01
  • 2020-07-11
  • 2017-06-24
  • 2019-10-26
  • 2022-12-14
  • 1970-01-01
  • 2018-02-18
  • 2012-04-18
相关资源
最近更新 更多