javascript - 如何在 Angular 2 中使用自定义 http 刷新访问 token ?

标签 javascript angular typescript oauth-2.0 refresh-token

我在我的应用程序中使用基于 token 的身份验证。我的后端是使用 restful 服务(spring)开发的。后端代码很好地生成了所需的访问 token 和带有时间线的刷新 token ,所以我用以下内容覆盖了 http 类:

export class customHttp extends Http {
   headers: Headers = new Headers({ 'Something': 'Something' });
    options1: RequestOptions = new RequestOptions({ headers: this.headers });
    private refreshTokenUrl = AppSettings.REFRESH_TOKEN_URL;
    constructor(backend: ConnectionBackend,
        defaultOptions: RequestOptions,private refresh:OauthTokenService) {
        super(backend, defaultOptions);
    }
    request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
    console.log("custom http ");
        return super.request(url, options)
            .catch((err) => {
                if (err.status === 401) {
                    console.log(" custome http 401 ");
                    //   refresh the token
                    this.refresh.refresh().subscribe((tokenObj)=>{
                              console.log("tokenobj ");
                    })
                 } else {
                    console.log("err " + err);
                }
            }); } } 

我在 refresh() 方法中刷新 token 时遇到了循环依赖错误,因此我尝试在另一个模块中使用刷新服务,但没有成功。我使用的方法与此 Handling refresh tokens using rxjs 中提到的相同任何帮助都会很棒!

最佳答案

这对我有用:

 request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
    //adding access token to each http request before calling super(..,..)
    let token = this.authenticationService.token;
    if (typeof url === 'string') {
        if (!options) {
            options = { headers: new Headers() };
        }
        options.headers.set('Authorization', `Bearer ${token}`);
    }
    else {
        url.headers.set('Authorization', `Bearer ${token}`);
    }
    return super.request(url, options)
      .catch((error) => {
            //if got authorization error - try to update access token
            if (error.status = 401) {
                return this.authenticationService.updateToken()
                    .flatMap((result: boolean) => {
                        //if got new access token - retry request
                        if (result) {
                            return this.request(url, options);
                        }
                        //otherwise - throw error
                        else {
                            return Observable.throw(new Error('Can\'t refresh the token'));
                        }

                    })
            }
            else {
                Observable.throw(error);
            }
        })
}

更新:authenticationService.updateToken() 实现应取决于您使用的授权提供者/授权机制。在我的例子中,它是 OAuth Athorization Server,因此实现基本上将正文中带有刷新 token 的发布请求发送到配置的 token url,并返回更新的访问和刷新 token 。 tokenEndPointUrl 由 OAuth 配置并颁发访问和刷新 token (取决于发送的 grant_type)。因为我需要刷新 token ,所以我将 grant_type 设置为 refresh_token。代码类似于:

updateToken(): Observable<boolean> {
    let body: string = 'refresh_token=' + this.refreshToken + '&grant_type=refresh_token';

    return this.http.post(tokenEndPointUrl, body, this.options)
        .map((response: Response) => {
            var returnedBody: any = response.json();
            if (typeof returnedBody.access_token !== 'undefined'){
              localStorage.setItem(this.tokenKey, returnedBody.access_token);
              localStorage.setItem(this.refreshTokenKey, returnedBody.refresh_token);
            return true;
        }
        else {
            return false;
        }
        })
}

希望对你有帮助

关于javascript - 如何在 Angular 2 中使用自定义 http 刷新访问 token ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42645350/

相关文章:

javascript - PHPStorm 配置 : How to remove background color on embedded html?

javascript - 如何使用 jQuery appendTo 在同一行中追加标签文本?

javascript - 为什么 datepicker() 接受参数 'getDate' ?

twitter-bootstrap - Angular 4 CLI,WebPack,为整个网站动态切换 Bootstrap 主题

javascript - Typescript 类引发事件

javascript - 编译CoffeeScript

Angular 错误 TS2322 : Type 'Promise<Dish[]>

Angular:ViewChild 音频元素作为 HTMLAudioElement?

typescript - Typescript 中带有 bool 值的可区分联合

angular - 无法检查 Protractor 中的状态指示器