【问题标题】:Renew access token with refresh token from personal api使用来自个人 api 的刷新令牌更新访问令牌
【发布时间】:2023-04-01 09:18:01
【问题描述】:

我有一个从 Angular 2 客户端调用的个人 REST API。我目前的认证流程如下:

  1. 用户使用电子邮件/密码登录
  2. 服务器验证并将 user_data、access_token(JWT) 和 refresh_token(存储在数据库中的不透明令牌)发送回客户端。
  3. 客户端在每次请求时发送 access_token。

在我的 API 上,我有一个端点 getAccessToken(String email, String refresh_token),它验证 refresh_token 并发出一个新的 access_token。

我的问题是:我应该使用我的 angular2 应用程序中的 refresh_token 在它过期之前或之后使用什么方法来请求新的 access_token。

我目前正在考虑在每个对 API 的 http 请求之前检查 access_token 是否过期,如下所示:

if (!tokenNotExpired("accessToken")) {
    this.classService.getAccessToken().subscribe(
        data => {
            // store new access_token in localStorage, then make request to get resource.
            this.classService.createClass().subscribe(
                data => {
                    //success
                }, error => {
                    //error
                })
        }, error => {
            // Invalid refresh token, redirect to login page.
        });
} else {
    this.classService.createClass().subscribe(
        data => {
            //success
        }, error => {
            //error
        });
}

有没有更好的方法来做到这一点?我正在使用 angular2-jwt 进行令牌验证。

【问题讨论】:

    标签: javascript angular jwt


    【解决方案1】:

    这看起来还不错。但是,如果您有许多不同的 API 调用(例如,不仅有 createClass(),还有 updateClass()destroyClass()),您最终可能不得不在源代码的许多不同位置进行相同的令牌过期检查,而这绝不是好东西。

    如何创建一项服务来处理所有呼叫的令牌到期/更新?

    此服务将作为可观察对象的工厂。您告诉它应该联系哪个端点以及将哪些数据发送到端点。该服务将根据您的 API 请求返回一个 observable。如果令牌过期,它会将您的 observable 包装在令牌刷新调用中。

    这只是一个伪代码,以获得大致的想法:

    class ApiService
    {
        constructor (private http: Http){}
    
        createRequest (endpoint, payload):Observable<any>
        {
            let request = 
            this.http.post(endpoint, payload, {headers:auth}).map(/* ... */);
    
            if (tokenExpired())
            {
              return this.refreshToken().flatMap( 
                (token) => {return request});
            }
            else
              return request;
        }
    
        refreshToken():Observable<string>
        {
            /* ... */
        }
    }
    

    使用此服务,您无需在其他任何地方检查令牌是否过期。只要确保您使用该服务来构建您的 API 调用,即在您的 createClass() 方法中。

    您甚至可以通过允许关闭授权的参数来增强createRequest 方法(例如,对于不需要授权的端点)。另一个参数可用于创建具有不同 HTTP 方法(PUT、GET)的调用。

    【讨论】:

    • 谢谢。你帮助了很多人。
    【解决方案2】:

    我试图模仿旧的滑动到期:

    在 auth.guard.ts 中:

    import { Injectable }                 from '@angular/core';
    import { Router, CanActivate }        from '@angular/router';
    import { tokenNotExpired,
             JwtHelper }                  from 'angular2-jwt';
    
    @Injectable()
    export class AuthGuard implements CanActivate {
      private jwtHelper = new JwtHelper();
    
      constructor(private router: Router) {}
    
    
      tokenValid() {
        this.handleSlidingExpiration();
        return tokenNotExpired();
      }
    
      canActivate() {
        if (tokenNotExpired()) {
          this.handleSlidingExpiration();
          return true;
        }
    
        this.router.navigate(['/login']);
        return false;
      }
    
      private handleSlidingExpiration() {
        let token = localStorage.getItem('id_token');
        if (!token) { return; }
    
        let expirationDate = this.jwtHelper.getTokenExpirationDate(token);
        let dToken = this.jwtHelper.decodeToken(token);
        let refreshLimit = new Date((dToken.iat + (dToken.exp - dToken.iat) / 2) * 1000);
    
        if(new Date() > refreshLimit) {
          // Here you can make a new side request for the new token and update it in local storage
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-06-12
      • 2022-01-23
      • 2019-06-29
      • 2014-09-13
      • 1970-01-01
      • 2020-07-12
      • 2016-08-13
      • 2022-12-23
      • 1970-01-01
      相关资源
      最近更新 更多