1
如果自定义http请求过期,我想刷新令牌。我尽我的代码时,我敢肯定,该令牌已过期,但它提供了以下控制台结果:自定义http请求之前的角度2刷新令牌
Token refresh is required app.js:1:92855
updateToken() method inside app.js:1:93301
tokenNotExpired?: false app.js:1:92674
Token refresh is required app.js:1:92855
updateToken() method inside app.js:1:93301
tokenNotExpired?: false app.js:1:92674
Token refresh is required app.js:1:92855
updateToken() method inside app.js:1:93301
tokenNotExpired?: false app.js:1:92674
Token refresh is required app.js:1:92855
updateToken() method inside app.js:1:93301
tokenNotExpired?: false app.js:1:92674
............ lots of the same sentences and finally exception:
EXCEPTION: Uncaught (in promise): Error: Error in :0:0 caused by: too much recursion
[email protected]://localhost/xxx/node_modules/zone.js/dist/zone.min.js:1:11750
............
正如我刷新是不言而喻的令牌进入一个无限循环中理解。我已经在其他地方用按钮测试了updateToken()方法,它工作正常。
我在做什么错?
自定义HTTP服务
import { Injectable } from '@angular/core';
import { Http, XHRBackend, RequestOptions, Request, RequestOptionsArgs, Response, Headers } from '@angular/http';
import { tokenNotExpired } from "angular2-jwt";
import { Observable } from "rxjs/Observable";
@Injectable()
export class HttpService extends Http {
constructor (backend: XHRBackend, options: RequestOptions) {
let token = localStorage.getItem('access_token'); // your custom token getter function here
options.headers.set('Authorization', `Bearer ${token}`);
super(backend, options);
}
request(url: string|Request, options?: RequestOptionsArgs): Observable<Response> {
let token = localStorage.getItem('access_token');
if (typeof url === 'string') { // meaning we have to add the token to the options, not in url
if (!options) {
// let's make option object
options = {headers: new Headers()};
}
options.headers.set('Authorization', `Bearer ${token}`);
} else { // we have to add the token to the url object
url.headers.set('Authorization', `Bearer ${token}`);
}
console.log("tokenNotExpired?: " + tokenNotExpired('access_token'));
if(tokenNotExpired('access_token')){ // if token is NOT expired
return super.request(url, options).catch(this.catchAuthError(this));
}else{ // if token is expired
console.log("Token refresh is required");
return this.updateToken()
.flatMap((result: boolean) => {
console.log("updateToken result");
console.log(result);
if (result) {
return super.request(url, options).catch(this.catchAuthError(this));
} else {
return Observable.throw(new Error('Can\'t refresh the token'));
}
});
}
}
updateToken(): Observable<any> {
console.log("updateToken() method inside");
let body: string = 'refresh_token=' + localStorage.getItem('refresh_token') + '&client_id=' + localStorage.getItem('resource') + '&grant_type=refresh_token';
return super.post(
localStorage.getItem("authUrl"),
body,
new RequestOptions({headers: new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' })})
)
.map((response: Response) => {
let returnedBody: any = response.json();
console.log("post returnedBody");
console.log(returnedBody);
if (typeof returnedBody.access_token !== 'undefined'){
localStorage.setItem('access_token', returnedBody.access_token);
localStorage.setItem('refresh_token', returnedBody.refresh_token);
console.log("Token Refreshed: refreshed access_token");
console.log(localStorage.getItem('access_token'));
return true;
}
else {
return false;
}
});
}
private catchAuthError (self: HttpService) {
return (res: Response) => {
console.log(res);
return Observable.throw(res);
};
}
}
应用模块
@NgModule({
imports: [ .......... ],
declarations: [ ....... ],
providers: [
{
provide: HttpService,
useFactory: (backend: XHRBackend, options: RequestOptions) => {
return new HttpService(backend, options);
},
deps: [XHRBackend, RequestOptions]
}
],
bootstrap: [ Application ]
})
updateToken()内的'super.post'将在内部调用'this.request' ...'this'是您自定义的'HttpService'。 – n00dl3
@ n00dl3那么我可以在不涉及“HttpService”的情况下调用帖子吗? –
不行,你应该调用'super.request'来代替。 (如果它当然没有调用任何重写方法)。 – n00dl3