如何使用Angular 2中的自定义HTTP刷新访问令牌



我在应用程序中使用基于令牌的身份验证。我的后端是使用Restful Service(Spring)开发的。后端代码非常好生成所需的访问令牌和使用时间表的刷新令牌,因此我已经超过了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);
                }
            }); } } 

当我遇到循环依赖性错误时,我会陷入刷新令牌()方法,因此我尝试在另一个模块中使用刷新服务,但没有运气。我使用的方法与此处理刷新代币中提到的方法相同,任何帮助都很好!

这对我有用:

 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服务器,因此实现基本上是在主体中使用Refresh令牌发送发布请求,以配置令牌URL并返回更新的访问和刷新令牌。TokenendPointUrl由OAuth配置,并且问题访问和刷新令牌(取决于已发送的Grant_Type)。因为我需要刷新令牌,所以我将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;
        }
        })
}

希望它有帮助

对于那些进入此页面而不了解它的人的人。

易于理解:

创建您的刷新令牌方法: //以某种方式检索刷新令牌

refreshToken(){
    let refreshToken = sessionStorage.getItem('refresh_token');
    let body = 'grant_type=refresh_token&refresh_token=' + refreshToken;
    var headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    headers.append('Authorization','Basic ' + btoa('something:something'));
    return this.http.post('your auth url',body,{headers: headers})
  }

比您的http请求中的

testService(){
    this.authHttp.get('your secured service url')
    .map(res => {
            return res;
        })
    .catch(error=> {
            if (error.status === 401) {
                return this.refreshToken().flatMap((newToken) => {
                  let newAccessToken = newToken.json();
                  sessionStorage.setItem('id_token', newAccessToken['access_token']);
                  sessionStorage.setItem('refresh_token', newAccessToken['refresh_token']);
                  return this.authHttp.request('your secured service url');
                })
            } else {
                return Observable.throw(error);
            }
        })
    .subscribe(res => console.log(res));
  }

不要忘记导入您需要的内容:

import { AuthHttp } from 'angular2-jwt';
import { Observable } from "rxjs/Observable";
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

请勿订阅您的刷新令牌方法。如果您这样做,您将在服务调用方法的平面图中看到一个大错误。

感谢您回复@dragonfly,这对我有用

    post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
        //check if the token is expired then set the latest token
                if (this.isTokenExpired) {
                    options.headers.set('Authorization', 'Bearer ' + localStorage.getItem("accessToken"));
   }
  return super.post(url, body, options)
         .catch((err) => {
  //if authentication error
      if (err.status === 401) {
       this.isTokenExpired = true;
      options.headers.set('Authorization', 'Bearer ' + localStorage.getItem("accessToken"));
    //refresh the token
 let refreshUrl = this.refreshTokenUrl;
    //pass the refresh token 
 refreshUrl = refreshUrl.replace(':refreshToken', localStorage.getItem("refreshToken"));
 //rest the access token
  return super.get(refreshUrl).mergeMap((tokenObj) => {
  localStorage.setItem("accessToken", tokenObj.json().value);
   // reset the headers
    options.headers.set('Authorization', 'Bearer ' + localStorage.getItem("accessToken"));
//retry the request with the new access token
return this.post(url, body, options)
 })
  .catch((refreshErr) => {
    if (refreshErr.status == 400) {
           console.log("refesh err");
    window.location.href = 'request=logout';
   }
 return Observable.throw(refreshErr);
  })
  } else {
  return err;
  }
 })
}

您能说出如何更新令牌(this.authenticationservice.updatetoken())?

相关内容

  • 没有找到相关文章

最新更新