我需要相关的建议来满足我的需求,即:
我在我的angular应用程序中实现了一个基于jWT的身份验证系统.当我获得新的令牌和刷新令牌时,我创建一个setTimeout,以便令牌可以在到期前刷新.但当我 bootstrap 应用程序(在我的AppComponents中)时,我也故意刷新我的 token ,我的问题与这种情况有关.
我从jWT获取已登录的用户信息,问题是,当应用程序正在 bootstrap 并执行令牌刷新时,令牌会在显示组件后存储,这导致应用程序获取之前令牌的用户信息而不是新创建的.
我们可以考虑使用解析器,但问题是,当使用解析器时,我将触发2个刷新令牌查询,一个在我的AppComponents中,另一个在解析器中,这不是我需要的行为.
所以基本上,这是我AppComponent的一部分:
ngOnInit() {
this.refreshToken();
...
}
private refreshToken() {
this.authSvc.refreshToken().pipe(
untilDestroyed(this),
catchError(error => {
if (error.status === 401) {
this.router.navigate(['/login']);
}
return of();
})
).subscribe();
}
以下是AuthService的一部分:
get user(): User | null {
const token = localStorage.getItem('token');
return token ? this.jwtHelper.decodeToken(token) : null;
}
refreshToken(): Observable<LoginResponse> {
return this.http.post<LoginResponse>(
`${environment.apiUrl}/token/refresh`,
{refresh_token: localStorage.getItem('refresh_token')}, this.CONTEXT
).pipe(
tap((res: LoginResponse) => this.storeTokens(res as LoginSuccess))
);
}
storeTokens(data: LoginSuccess): void {
localStorage.setItem('token', data.token);
localStorage.setItem('refresh_token', data.refresh_token);
this.scheduleTokenRefresh(data.token);
}
这里有一个我需要用户数据的组件(它不会是唯一需要此数据的组件):
export class HomeComponent implements OnInit {
user!: User | null;
constructor(private authSvc: AuthService) {
}
ngOnInit() {
this.user = this.authSvc.user;
}
我面临的问题是,Home组件在storeTokens被调用之前就已显示,因此,如果用户数据自上一个令牌以来已在后台更新,那么我的HomeComponents将不会知道它,因为它将使用之前的令牌..
我try 使用解析器错误,它迫使我再次调用refreshToken,但这不是我想要的.我需要将我的refreshToken保存在AppComponents中,并且不要调用它两次.这是解决方案:
export const tokenRefreshedResolver: ResolveFn<boolean> = (route, state) => {
return inject(AuthService).refreshToken().pipe(
map(() => true),
catchError(() => of(false))
);
};
合适的解决方案是什么?