我想通过从api中捕获401来刷新access_token。我正在使用laravel 5护照。
在extended-http.service.ts
我的代码中捕获401之后,我的代码不会发送帖子请求以获得更新access_token
。
我尝试过多种方法,但我唯一可以使用的是以下代码。这段代码的问题是我必须将它添加到我的应用程序内的每个请求中,这是不理想的。我宁愿刷新extended-http.service.ts
401 catch中的令牌。
.catch(initialError => {
if (initialError && initialError.status === 401) {
console.log('we got here');
this.RefreshService.refresh().flatMap((data) => {
if (localStorage.getItem("access_token") != null) {
// retry with new token
return this.getUsers();
} else {
return Observable.throw(initialError);
}
});
} else {
return Observable.throw(initialError);
}
})
以下代码是我现在要捕获的401.但是当我尝试在捕手内部调用this.refreshToken.refresh();
时,我收到以下错误:Cannot instantiate cyclic dependency! Http ("[ERROR ->]"): in NgModule AppModule in ./AppModule@-1:-1
// app.module.ts
import { ExtendedHttpService } './services/extended-http.service.ts';
providers: [
RefreshService
{provide: Http, useClass: ExtendedHttpService },
]
// refresh.service.ts
import { Injectable } from '@angular/core';
import { Request, XHRBackend, RequestOptions, Response, Http, RequestOptionsArgs, Headers, URLSearchParams } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import * as globals from './../globals';
import { CustomQueryEncoderHelper } from './../shared/helpers';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
@Injectable()
export class RefreshService {
constructor(private http: Http) { }
refresh() {
let body = new URLSearchParams('', new CustomQueryEncoderHelper());
body.set('grant_type', 'refresh_token');
body.set('refresh_token', localStorage.getItem('refresh_token'));
body.set('client_id', '2');
body.set('client_secret', 'Crazy secret code');
let headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
let options = new RequestOptions({ headers: headers });
return this.http.post(globals.api + 'oauth/token', body, options)
.map(res => res.json())
.subscribe((data) => {
console.log(data);
localStorage.removeItem("access_token");
localStorage.removeItem("refresh_token");
localStorage.removeItem("expires_in");
localStorage.setItem("access_token", data.access_token);
localStorage.setItem("refresh_token", data.refresh_token);
localStorage.setItem("expires_in", data.expires_in);
location.reload();
},
(error) => {
Observable.throw(error);
}
);
}
}
//扩展http.service.ts
import { Injectable } from '@angular/core';
import { Request, XHRBackend, RequestOptions, Response, Http,
RequestOptionsArgs, Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
@Injectable()
export class ExtendedHttpService extends Http {
constructor(backend: XHRBackend, defaultOptions: RequestOptions) {
super(backend, defaultOptions);
}
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
return super.request(url, options).catch((error: Response) => {
if ((error.status === 401 || error.status === 403) &&
(window.location.href.match(/\?/g) || []).length < 2) {
console.log('The authentication session expires or the user is not authorised. Force refresh of the current page.');
this.refreshToken.refresh(); // Doesn't work
// How can i refresh token here?
}
return Observable.throw(error);
});
}
}
所以回顾一下我想在extended.service.ts
401 catch中刷新令牌。但我不知道我应该如何让它发挥作用。请帮忙!
答案 0 :(得分:1)
我遇到了同样的问题,但是我找到了解决问题的方法。
import { Injectable, Injector } from '@angular/core';
constructor(public toastr: ToastrService, public toastrConfig: ToastrConfig, private router: Router,
private injector: Injector, private cookieService: CookieService) {
toastrConfig.closeButton = true;
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.ingestionService = this.injector.get(IngestionService);
// HERE i create an instance of that.
}