Проблема в том, что, когда срок действия access token
истек, и я делаю любой щелчок, токен доступа не обновляется. Но когда я делаю второй щелчок, он обновляется. За первый клик я получаю «GET 401 error
». Реальная проблема для меня - получить токен доступа перед любым HTTP-запросом в interceptor
.
Я попытался switchMap
, чтобы мой код дождался токена доступа, но он не работал.
У вас есть идеи, как я могу это исправить?
export class DevelopmentInterceptor implements HttpInterceptor {
constructor(
private authService: AuthService,
private router: Router,
private toastr: ToastrService,
private translate: TranslateService
) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const headers = new HttpHeaders({
'Content-Type': 'application/json; charset=utf-8',
'Authorization': `Bearer ${this.authService.getAccessToken()}`
});
let apiReq = null;
if (req.url.indexOf('i18n') >= 0) {
apiReq = req;
} else if (req.url.indexOf('token') >= 0) {
apiReq = req.clone({ url: environment.authServerUrl + `${req.url}` });
} else if (req.url.indexOf('sign-up') >= 0) {
apiReq = req.clone({ url: environment.signupUrl });
} else if (req.url.indexOf('api/users') >= 0 || req.url.indexOf('api/roles') >= 0 || req.url.indexOf('api/permissions') >= 0) {
apiReq = req.clone({ headers: headers, url: environment.authServerUrl + `${req.url}` });
} else {
apiReq = req.clone({ headers: headers, url: environment.backenUrl + `${req.url}` });
}
if (req.url.endsWith('token')) {
return next.handle(apiReq).catch((err: any) => { //<--if error use a catch
if (err instanceof HttpErrorResponse) {
return this.handleError(err);
}
});
} else {
return this.authService.checkExpiry().switchMap( (result) => {
if (result) {
return next.handle(apiReq)
.catch((err: any) => { // <--if error use a catch
if (err instanceof HttpErrorResponse) {
return this.handleError(err);
}
});
}
} )
}
}
private handleError(err: Response | any) {
...
}
}
public checkExpiry() : Observable<any> {
if (!this.cookieService.get('user_id')) {
this.removeTokens(); // not logged in
return Observable.of(true);
} else if (!this.cookieService.check('access_token')) {
if (this.cookieService.check('refresh_token')) {
if (this.secondsTillExpiry('refresh_token') > 0) {
return this.refreshAccessToken().switchMap((data:any) => {
if (data) {
this.saveTokenInCookies(data);
this.updateExpiration(data);
return Observable.of(true);
}
})
} else {
this.router.navigate(['/login']);
this.removeTokens();
return Observable.of(true);
}
}
} else if (this.cookieService.check('access_token') ) {
return Observable.of(true);
}
}
public secondsTillExpiry(tokenMode: string): any {
if (tokenMode == 'access_token') {
return ((new Date(1970, 0,
1).setSeconds(jwt_decode(this.getAccessToken()).exp)) -
(Math.round(Date.now()) / 1000));
} else if (tokenMode == 'refresh_token') {
return ((new Date(1970, 0,
1).setSeconds(jwt_decode(this.getRefreshToken()).exp)) -
(Math.round(Date.now()) / 1000));
}
}
private refreshAccessToken(): Observable<Object> {
const params = 'refresh_token=' + this.getRefreshToken() +
'&grant_type=refresh_token';
return this.http.post(this.authUrl, params, this.getOptions());
}