【问题标题】:How to Check JWT token expiration before calling Api from Angular to .NET-core如何在从 Angular 调用 Api 到 .NET-core 之前检查 JWT 令牌过期
【发布时间】:2021-10-30 14:09:03
【问题描述】:

我使用 angular 作为客户端,使用 asp.net-core 作为服务器。我正在从服务器创建 JWT 令牌和刷新令牌并将其传递给 Angular 并将其存储在本地存储中。我将我的 JWT 令牌验证 5 分钟并将令牌刷新为 2 天。我面临的问题是我的令牌已过期,并且我在页面上只有经过身份验证的用户才能访问具有有效 jwt 令牌的用户,直到我刷新我的页面或转到另一个 URL 我的身份验证不会出现,也不会了解我们的令牌已过期,因此如果发生调用 [authorize]Api 的事件,我们的调用将因令牌过期而被拒绝。所以我想知道在调用服务器 api 之前有什么方法可以检查令牌是否过期

这是我的 AuthGurd


  constructor (private _authService: AuthService, private _router: Router) {}

  async canActivate(): Promise<boolean>{
    if(await this._authService.isUserAuthenticated() === true){
      return true;
    }
    else{
      this._router.navigate([RouteConstant.SIGN_IN]);
      return false;
    }
  }
public async isUserAuthenticated(): Promise<boolean>{
    if(this._storageService.getToken() !== null){
      if(!this._jwtHelperService.isTokenExpired(this._storageService.getToken()?.toString())){
        return true;
      }
      else{
        if(!this._storageService.refreshTokenExists()){
          return false;
        }
        else{
          let authTokenClient: AuthTokenClient = {
            token: this._storageService.getToken() as string,
            refreshToken: this._storageService.getRefreshToken() as string
          };
            return await this.refreshAuthToken(authTokenClient);
            !this._jwtHelperService.isTokenExpired(this._storageService.getToken()?.toString());
        }
      }
    }
    else{
      return false;
    }
  }
  }

  public setAuth(authToken: AuthToken){
    this._storageService.saveToken(authToken.token?.toString());
    this._storageService.saveRefreshToken(authToken.refreshToken);
  }
  public async refreshAuthToken(authTokenClient: AuthTokenClient) {
    const response = await this._http.post<AuthToken>(environment.apiHost + UrlConstant.ACCOUNT_REFRESH, authTokenClient,{observe: 'response'}).toPromise();
    console.log(response);
    const newToken = (<any>response).body.token;
            console.log(newToken);
            const newRefreshToken = (<any>response).body.refreshToken;
            console.log(newRefreshToken);
            localStorage.setItem("token", newToken);
            localStorage.setItem("refreshToken",newRefreshToken);
            if (newToken && newRefreshToken == null){
              return false
            }
            else {
              return true;
            }
  }
  
  
}

我尝试在每次调用 api 之前验证 jwt 令牌,我通过 我在这里 app.component.ts

async clickEvent(){
    if (await this._authService.isUserAuthenticated()==true)
    return this.api();
  else{
    this.logout();
  }
}
  public api(){
    this._http.get("http://localhost:15363/WeatherForecast").subscribe(response => {
 console.log(response);
    }, err => {
      console.log(err)
    });
  }

app.component.html

<div>
    <button  (click)="clickEvent()" >
        Click Me</button>
</div>

c# Angular 调用的代码 Api

 [HttpGet]
        [Authorize]
        public IEnumerable<WeatherForecast> Get()
        {
            var rng = new Random();
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            })
            .ToArray();
        }

但我认为这不是一个调用的最佳方法,它是有效的,但在应用程序中,我们有很多调用,我们不能每次都使用这个 if else 语句

【问题讨论】:

    标签: c# angular jwt refresh-token


    【解决方案1】:

    您可能会解码 JWT 令牌,理论上它将包括令牌的过期时间戳。

    尝试在此处解码您的其中一个令牌的示例:https://jwt.io/ 并查看是否包含过期时间的属性。

    这里有一些关于如何最好地处理这个问题的好答案:

    How to check if JWT token is expired in Angular 8

    【讨论】:

      【解决方案2】:

      优化

      当从授权服务器接收到访问令牌时,JSON 响应会包含一个 expires_in 字段。客户端可能会使用它通过某种后台计时器或线程静默更新访问令牌。

      可靠的选择

      所有 OAuth clenits 都应该通过尝试获取新的访问令牌,然后重试 API 调用来处理来自 API 的 401 响应 - 有关示例,请参阅 this Curity API Client class。可能出于以下原因需要它:

      • API 和授权服务器之间的时钟差异
      • 令牌签名证书续订
      • 我可以描述的某些基础架构设置

      尝试可靠的选择

      在我的Quick Start Page 上登录我的在线单页应用程序,然后单击Expire Access TokenReload Data 按钮。最终用户应该不会注意到减速,并且只需要对一小部分 API 请求进行更新。考虑使用更长的访问令牌生命周期 - 可能是 15 分钟。

      摘要

      在我使用 OAuth 的所有这些年中,我一直使用可靠的选项,并且从不为优化而烦恼。这也使我的代码保持简单。

      【讨论】:

        猜你喜欢
        • 2020-06-30
        • 2018-06-19
        • 2018-10-07
        • 2017-08-20
        • 2021-07-22
        • 2021-06-27
        • 2020-10-28
        • 2019-12-22
        • 1970-01-01
        相关资源
        最近更新 更多