当用户登录时,他们会获得token_a。要在应用程序中发出任何API请求,他们需要token_b。 token_b是使用token_a生成的。
我已经构建了一个身份验证拦截器,它在用户登录后将token_b附加到所有后续api调用的头部。但是,token_b上有一个很短的到期时间,因此必须重新生成token_b。
auth.interceptor.ts
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent, HttpResponse, HttpClient, HttpBackend } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';
import { AuthService } from './../services/auth/auth.service';
import { JwtService } from './../services/jwt/jwt.service';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
private httpClient: HttpClient;
constructor(private auth: AuthService, private jwt: JwtService, private http: HttpBackend) {
this.httpClient = new HttpClient(http);
}
setHeader(req) {
const authToken = this.auth.getProfileToken();
const authReq = req.clone({
headers: req.headers.set('Authorization', 'Bearer ' + authToken)
});
return authReq;
}
intercept(req: HttpRequest<any>, next: HttpHandler) {
const InterceptorSkipHeader = 'X-Skip-Interceptor';
if (req.headers.has(InterceptorSkipHeader)) {
const headers = req.headers.delete(InterceptorSkipHeader);
return next.handle(req.clone({ headers }));
}
if (this.auth.hasProfileToken() && this.auth.isProfileTokenExpired()) {
const result = this.refreshToken();
const ar = this.setHeader(req);
return next.handle(ar);
}
const authReq = this.setHeader(req);
return next.handle(authReq);
}
async refreshToken() {
const token = localStorage.getItem('token');
return await this.httpClient.post('//api/v1/users/login', { 'token': token })
.subscribe((res: any) => {
localStorage.setItem('profile_token', res.token);
return res;
});
}
}
在拦截器函数中,我检查profileToken(token_b)是否存在以及它是否已过期。如果是我试图调用设置新令牌的refreshToken。
然而,在拦截器传递请求之前,我发现refreshToken没有完成。
答案 0 :(得分:0)
由于refreshToken()
是异步函数,因此您需要在传递请求之前等待它完成。一种方法是将refreshToken()
链接/管道传输到next.handle(ar)
:
intercept(req: HttpRequest<any>, next: HttpHandler) {
const InterceptorSkipHeader = 'X-Skip-Interceptor';
if (req.headers.has(InterceptorSkipHeader)) {
const headers = req.headers.delete(InterceptorSkipHeader);
return next.handle(req.clone({ headers }));
}
if (this.auth.hasProfileToken() && this.auth.isProfileTokenExpired()) {
return this.refreshToken().switchMap(() => {
const ar = this.setHeader(req);
return next.handle(ar);
});
}
const authReq = this.setHeader(req);
return next.handle(authReq);
}
refreshToken() {
const token = localStorage.getItem('token');
return this.httpClient.post('//api/v1/users/login', { 'token': token })
.map((res: any) => {
localStorage.setItem('profile_token', res.token);
return res;
});
}