admin管理员组文章数量:1304248
I am using token based authentication in my application. My backend is developed using restful service(spring).The backend code is very well generating the required the access token and refresh tokens with timelines, So I have overidden the http class with following:
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);
}
}); } }
I am getting stuck in refreshing the token at refresh() method as I am getting cyclic dependency error so I tried to use refresh service in another module but no luck. I am using the same approach as mentioned in this Handling refresh tokens using rxjs Any help would be great!
I am using token based authentication in my application. My backend is developed using restful service(spring).The backend code is very well generating the required the access token and refresh tokens with timelines, So I have overidden the http class with following:
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);
}
}); } }
I am getting stuck in refreshing the token at refresh() method as I am getting cyclic dependency error so I tried to use refresh service in another module but no luck. I am using the same approach as mentioned in this Handling refresh tokens using rxjs Any help would be great!
Share Improve this question edited May 23, 2017 at 11:54 CommunityBot 11 silver badge asked Mar 7, 2017 at 10:08 AliAli 1073 silver badges9 bronze badges3 Answers
Reset to default 6This is what worked for me:
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);
}
})
}
UPDATE: authenticationService.updateToken() implementation should depend on authorization provider/authorization mechanism you use. In my case it is OAuth Athorization Server, so implementation basically sends post request with refresh token in the body to configured token url and returns updated access and refresh tokens. tokenEndPointUrl is configured by OAuth and issues access and refresh tokens (depending on grant_type sent). Because i need to refresh token i set grant_type to refresh_token. Code looks similar to:
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;
}
})
}
Hope it helps
For those who get to this page and don't understand a thing from it.
The easy to understand:
Create your refresh token method: //retrieve the refresh token somehow
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})
}
Than in your http request (mine uses the angular-jwt authHttp instead of 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));
}
Do not forget to import what you need like:
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';
Do not subscribe in your refresh token method. If you do you will see a big error in the flatmap of the service call method.
thanks for replying @dragonfly, this worked for me
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;
}
})
}
Can you tell how are you updating the token(this.authenticationService.updateToken())?
本文标签: javascripthow to refresh the access token using custom http in angular 2Stack Overflow
版权声明:本文标题:javascript - how to refresh the access token using custom http in angular 2? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741782392a2397385.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论