Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 角度-如何使用身份验证拦截器刷新JWT令牌_Angular_Angular Http - Fatal编程技术网

Angular 角度-如何使用身份验证拦截器刷新JWT令牌

Angular 角度-如何使用身份验证拦截器刷新JWT令牌,angular,angular-http,Angular,Angular Http,当用户登录时,他们会获得令牌。要在应用程序中发出任何API请求,它们需要令牌。令牌_b是使用令牌_a生成的 我构建了一个身份验证拦截器,它在用户登录后将token_b附加到所有后续api调用的头中。但是,令牌_b的过期时间很短,因此,如果令牌_b过期,则必须重新生成 auth.interceptor.ts import { Injectable } from '@angular/core'; import { HttpInterceptor, HttpHandler, HttpRequest,

当用户登录时,他们会获得令牌。要在应用程序中发出任何API请求,它们需要令牌。令牌_b是使用令牌_a生成的

我构建了一个身份验证拦截器,它在用户登录后将token_b附加到所有后续api调用的头中。但是,令牌_b的过期时间很短,因此,如果令牌_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;
            });

    }

}
从'@angular/core'导入{Injectable};
从“@angular/common/http”导入{HttpInterceptor、HttpHandler、HttpRequest、HttpEvent、HttpResponse、HttpClient、HttpBackend};
从“rxjs/Observable”导入{Observable};
导入'rxjs/add/operator/do';
从“/../services/auth/auth.service”导入{AuthService};
从“/../services/jwt/jwt.service”导入{JwtService};
@可注射()
导出类AuthInterceptor实现HttpInterceptor{
私有httpClient:httpClient;
构造函数(私有auth:AuthService、私有jwt:JwtService、私有http:HttpBackend){
this.httpClient=新的httpClient(http);
}
setHeader(请求){
const authToken=this.auth.getProfileToken();
const authReq=req.clone({
headers:req.headers.set('Authorization','Bearer'+authToken)
});
返回authReq;
}
拦截(请求:HttpRequest,下一步:HttpHandler){
const InterceptorSkipHeader='X-Skip-Interceptor';
if(请求标头has(拦截器KipHeader)){
const headers=req.headers.delete(InterceptorSkipHeader);
返回next.handle(req.clone({headers}));
}
if(this.auth.hasProfileToken()&this.auth.isProfileTokenExpired()){
const result=this.refreshtToken();
常量ar=此.setHeader(req);
返回下一个。处理(ar);
}
const authReq=此.setHeader(req);
返回next.handle(authReq);
}
异步刷新令牌(){
const token=localStorage.getItem('token');
return wait this.httpClient.post('//api/v1/users/login',{'token':token})
.订阅((res:any)=>{
setItem('profile_token',res.token);
返回res;
});
}
}
在拦截器函数中,我检查profileToken(token_b)是否存在,以及它是否过期。如果是,我尝试调用refreshToken来设置新的令牌

但是,在拦截器传递请求之前,我发现refreshToken没有完成。

因为
refreshToken()
是一个异步函数,所以在传递请求之前需要等待它完成。一种方法是将
refreshtToken()
链接/管道到
next.handle(ar)

intercept(请求:HttpRequest,下一步:HttpHandler){
const InterceptorSkipHeader='X-Skip-Interceptor';
if(请求标头has(拦截器KipHeader)){
const headers=req.headers.delete(InterceptorSkipHeader);
返回next.handle(req.clone({headers}));
}
if(this.auth.hasProfileToken()&this.auth.isProfileTokenExpired()){
返回此.refreshToken().switchMap(()=>{
常量ar=此.setHeader(req);
返回下一个。处理(ar);
});
}
const authReq=此.setHeader(req);
返回next.handle(authReq);
}
刷新令牌(){
const token=localStorage.getItem('token');
返回此.httpClient.post('//api/v1/users/login',{'token':token})
.map((res:any)=>{
setItem('profile_token',res.token);
返回res;
});
}

像您的示例一样使用switchmap时,我会得到“switchmap在类型Promise上不存在”,但如果我不想将刷新令牌存储在本地存储器中,该怎么办?
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;
        });

}