【发布时间】:2021-07-30 04:30:54
【问题描述】:
我正在尝试实现这个angular refresh token interceptor(也来自this stackoverflow),但是在将 refreshToken 函数更改为返回 this.http.get 观察者而不是 rxjs of 时遇到问题strong> 运算符。
它与 of 一起工作正常,但是一旦我更改为 http.get return 它就不会触发 get 调用并且不会发出任何东西,也不会进入下一个concat 观察者订阅。
无法弄清楚为什么它不起作用。任何帮助表示赞赏。
拦截器文件:
export class CaughtInterceptor implements HttpInterceptor {
constructor(private authService: AuthService) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let retries = 0;
return this.authService.token$.pipe(
map(token => req.clone({ setHeaders: { Authorization: `Bearer ${token}` } })),
concatMap(authReq => next.handle(authReq)),
// Catch the 401 and handle it by refreshing the token and restarting the chain
// (where a new subscription to this.auth.token will get the latest token).
catchError((err, restart) => {
// If the request is unauthorized, try refreshing the token before restarting.
if (err.status === 401 && retries === 0) {
retries++;
return concat(this.authService.refreshToken$, restart);
}
if (retries > 0) {
this.authService.logout();
}
return throwError(err);
})
);
}
}
auth.service 文件:
export interface RefreshTokenResult {
accessToken: string;
}
@Injectable()
export class AuthService {
private tokenSubject$ = new BehaviorSubject<string | null>(null);
token$ = this.tokenSubject$.pipe(
filter((token) => token !== null),
take(1)
);
refreshToken$: Observable<any> = defer(() => {
if (this.tokenSubject$.value === null) {
return this.token$;
}
// Defer allows us to easily execute some action when the Observable
// is subscribed. Here, we set the current token to `null` until the
// refresh operation is complete. This ensures no requests will be
// sent with a known bad token.
this.tokenSubject$.next(null);
return this.refreshToken().pipe(
tap((res) => {
this.tokenSubject$.next(res.accessToken);
}),
catchError((err) => {
this.logout();
throw err;
})
);
});
get token(): string | null {
return this.tokenSubject$.value;
}
authenticate(): void {
this.tokenSubject$.next('someToken');
}
refreshToken(): Observable<RefreshTokenResult> {
// Changed of to this.http.get here
return this.http.get<RefreshTokenResult>(url).pipe(delay(0));
/*
return of({
accessToken: 'newToken',
}).pipe(
delay(0),
);
*/
}
logout(): void {}
}
【问题讨论】:
-
任何控制台错误?也许您为了简洁而省略了它,但我看不到您将
http注入 auth.service 的位置,以便您可以使用 this.http