【发布时间】:2021-12-08 10:02:54
【问题描述】:
您好,我正在尝试检查令牌何时即将到期并使用访问令牌重新加载它。 主要问题是要重新加载它,我必须进行 http 调用以获取新令牌,然后将其重新保存在会话存储中。 主要问题是,因为 http 是异步的,它会重新加载令牌,但是因为我不知道如何等到此调用完成后再使用新令牌重试原始调用,所以它失败了。
这是代码:
身份验证服务: 这是被调用来更新令牌的服务
async reloadIdTokenFromAccess(accessToken : string | null) {
console.log("Performing call to reload token");
const resp = await this.httpClient.post<IdTokenDTO>(`${environment.backendUrl}/auth/tokenReload`,accessToken).toPromise();
this.setIdToken(resp.idToken);
this.setExpireAt(resp.expireAt);
console.log("Data update in session storage")
}
拦截器
@Injectable()
export class HttpTokenInterceptor implements HttpInterceptor {
constructor(private authServ : AuthService) {}
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
let token: string | null = this.authServ.getIdToken();
let expiration: number | null = this.authServ.getExpireAt();
let reloaded : boolean = false;
var currentTime = new Date().getTime();
if(expiration != null && !request.url.includes("tokenReload") && !request.url.includes("login")){
if(expiration <= currentTime + 60000 && this.authServ.getAccessToken() != null){
reloaded = true;
console.log("Token expiration Time near to expire, reloading token")
this.authServ.reloadIdTokenFromAccess(this.authServ.getAccessToken());
token = this.authServ.getIdToken();
console.log("Finish all full reloading")
}
}
if(reloaded){
console.log("Starting the request with the new token")
}
let originalReq = request;
if(token){
request = originalReq.clone({
setHeaders: {
authorization: `Bearer ${ token }`,
'Content-Type': 'application/json'
}
});
}
return next.handle(request);
}
}
您可以在重新加载令牌之前检查请求是否正在执行。 在继续该方法之前如何强制完成此请求?
类似于 java 中的 CompletableFuture 使用 get() 方法来阻止代码直到它完成
我也有这样的测试没有成功
async reloadIdTokenFromAccess(accessToken : string | null) {
console.log("Performing call to reload token");
await this.httpClient.post<IdTokenDTO>(`${environment.backendUrl}/auth/tokenReload`,accessToken).subscribe( (resp : IdTokenDTO) => {
this.setIdToken(resp.idToken);
this.setExpireAt(resp.expireAt);
console.log("updates token in session storage")
})
}
import { Injectable } from '@angular/core';
import {HttpRequest,HttpHandler,HttpEvent,HttpInterceptor} from '@angular/common/http';
import { from, Observable, Subscription } from 'rxjs';
import { AuthService } from '../services/auth.service';
@Injectable()
export class HttpTokenInterceptor implements HttpInterceptor {
constructor(private authServ : AuthService) {}
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
return from(this.handle(request, next));
}
async handle(request: HttpRequest<any>, next: HttpHandler) {
const expiration: number | null = this.authServ.getExpireAt();
const currentTime = new Date().getTime();
let reloaded: boolean = false;
if (expiration != null && !request.url.includes('tokenReload') &&!request.url.includes('login')) {
if (expiration <= currentTime + 60000 && this.authServ.getAccessToken() != null) {
reloaded = true;
console.log('Token expiration Time near to expire, reloading token');
await this.authServ.reloadIdTokenFromAccess(this.authServ.getAccessToken());
console.log('Finish of call reaload token');
}
}
const token = this.authServ.getIdToken();
if (reloaded){
console.log('Starting the request with the new token');
}
const originalReq = request;
if (token) {
request = originalReq.clone({
setHeaders: {
authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
}
return next.handle(request).toPromise();
}
}
我很绝望。不知道该做什么(也许继续学习课程和教程,但我有 dedlines):(
提前致谢。
【问题讨论】:
-
我猜你应该在拦截器中等待你的承诺?
-
在
this.authServ.reloadIdTokenFromAccess(this.authServ.getAccessToken());在线调用时,您永远不会等待承诺完成,您必须使用then或async/await。老实说,虽然我会尽量保持这一切一致,并为堆栈中的所有内容使用 RxJs 或使用 Promise。我的偏好是 RxJs。 -
@Igor 你能解释得更好吗,我有点新手,实际上我的问题是我不知道如何让代码等到承诺完成
-
this.authServ.reloadIdTokenFromAccess返回什么?它是可观察的还是承诺?
标签: angular async-await promise jwt interceptor