gpt4 book ai didi

javascript - 拦截器 Angular 6 中的刷新 token (JWT)

转载 作者:太空狗 更新时间:2023-10-29 18:00:32 52 4
gpt4 key购买 nike

最初,我有一个函数可以简单地检查 token 是否存在,如果不存在,则将用户发送到登录 header 。现在我需要借助刷新 token 实现 token 到期时刷新 token 的逻辑。但是我得到一个错误 401。刷新函数没有时间工作,拦截器中的工作进一步导致错误。如何修复代码以便我可以等待刷新完成、获取新 token 而不是重定向到登录页面?

token 拦截器

import {HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from "@angular/common/http";
import {Injectable, Injector} from "@angular/core";
import {AuthService} from "../services/auth.service";
import {Observable, throwError} from "rxjs";
import {catchError, tap} from "rxjs/operators";
import {Router} from "@angular/router";
import {JwtHelperService} from "@auth0/angular-jwt";

@Injectable({
providedIn: 'root'
})
export class TokenInterceptor implements HttpInterceptor{

private auth: AuthService;

constructor(private injector: Injector, private router: Router) {}

jwtHelper: JwtHelperService = new JwtHelperService();

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

this.auth = this.injector.get(AuthService);

const accToken = this.auth.getToken();
const refToken = this.auth.getRefreshToken();

if ( accToken && refToken ) {

if ( this.jwtHelper.isTokenExpired(accToken) ) {
this.auth.refreshTokens().pipe(
tap(
() => {
req = req.clone({
setHeaders: {
Authorization: `Bearer ${accToken}`
}
});
}
)
)
} else {
req = req.clone({
setHeaders: {
Authorization: `Bearer ${accToken}`
}
});
}

}
return next.handle(req).pipe(
catchError(
(error: HttpErrorResponse) => this.handleAuthError(error)
)
);
}

private handleAuthError(error: HttpErrorResponse): Observable<any>{
if (error.status === 401) {
this.router.navigate(['/login'], {
queryParams: {
sessionFailed: true
}
});
}
return throwError(error);
}

}

授权服务

import {Injectable} from "@angular/core";
import {HttpClient, HttpHeaders} from "@angular/common/http";
import {Observable, of} from "rxjs";
import {RefreshTokens, Tokens, User} from "../interfaces";
import {map, tap} from "rxjs/operators";

@Injectable({
providedIn: 'root'
})
export class AuthService{

private authToken = null;
private refreshToken = null;

constructor(private http: HttpClient) {}

setToken(authToken: string) {
this.authToken = authToken;
}

setRefreshToken(refreshToken: string) {
this.refreshToken = refreshToken;
}

getToken(): string {
this.authToken = localStorage.getItem('auth-token');
return this.authToken;
};

getRefreshToken(): string {
this.refreshToken = localStorage.getItem('refresh-token');
return this.refreshToken;
};

isAuthenticated(): boolean {
return !!this.authToken;
}

isRefreshToken(): boolean {
return !!this.refreshToken;
}

refreshTokens(): Observable<any> {

const httpOptions = {
headers: new HttpHeaders({
'Authorization': 'Bearer ' + this.getRefreshToken()
})
};

return this.http.post<RefreshTokens>('/api2/auth/refresh', {}, httpOptions)
.pipe(
tap((tokens: RefreshTokens) => {
localStorage.setItem('auth-token', tokens.access_token);
localStorage.setItem('refresh-token', tokens.refresh_token);
this.setToken(tokens.access_token);
this.setRefreshToken(tokens.refresh_token);
console.log('Refresh token ok');
})
);
}

}

最佳答案

在您的示例中,您从不订阅您的 refreshTokens().pipe() 代码。没有订阅,可观察对象将不会执行。

关于javascript - 拦截器 Angular 6 中的刷新 token (JWT),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52965491/

52 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com