gpt4 book ai didi

Angular 8 Intercept 调用刷新 token

转载 作者:行者123 更新时间:2023-12-01 11:12:50 24 4
gpt4 key购买 nike

如果当前访问 token 已过期,我正在尝试刷新访问 token 。

我一次发送多个请求,我想创建一种队列,因此其他请求不会请求刷新 token 路由。

我在谷歌上搜索了一些最佳实践和示例,并为 Angular 6 和 rxjs v6 找到了以下解决方案,它使用了 BehaviourSubject 和 switchMaps。 (请看附件代码)

但是我使用的是 Angular 8 (8.1) 和 rxjs v6.4,这个解决方案对我不起作用。

它根本没有到达switchMapthis.authService.requestAccessToken().pipe . (使用console.log测试)

但是,如果我评论 return this.refreshTokenSubject.pipe并返回 next.handle(request)它到达那个 switchMap,但我的其他请求失败了。

您知道是否有任何更改,或者我应该尝试以其他方式执行此操作吗?

  • token 拦截器
  •     import { Injectable } from '@angular/core';
    import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
    import { AuthService } from './auth.service';
    import { Observable, BehaviorSubject, Subject } from 'rxjs';
    import { switchMap, take, filter } from 'rxjs/operators';
    @Injectable()
    export class TokenInterceptor implements HttpInterceptor {
    private refreshTokenInProgress = false;
    private refreshTokenSubject: Subject<any> = new BehaviorSubject<any>(null);

    constructor(public authService: AuthService) { }
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    const accessExpired = this.authService.isAccessTokenExpired();
    const refreshExpired = this.authService.isRefreshTokenExpired();

    if (accessExpired && refreshExpired) {
    return next.handle(request);
    }
    if (accessExpired && !refreshExpired) {
    if (!this.refreshTokenInProgress) {
    this.refreshTokenInProgress = true;
    this.refreshTokenSubject.next(null);
    return this.authService.requestAccessToken().pipe(
    switchMap((authResponse) => {
    this.authService.saveToken(AuthService.TOKEN_NAME, authResponse.accessToken);
    this.authService.saveToken(AuthService.REFRESH_TOKEN_NAME, authResponse.refreshToken);
    this.refreshTokenInProgress = false;
    this.refreshTokenSubject.next(authResponse.refreshToken);
    return next.handle(this.injectToken(request));
    }),
    );
    } else {
    return this.refreshTokenSubject.pipe(
    filter(result => result !== null),
    take(1),
    switchMap((res) => {
    return next.handle(this.injectToken(request))
    })
    );
    }
    }

    if (!accessExpired) {
    return next.handle(this.injectToken(request));
    }
    }

    injectToken(request: HttpRequest<any>) {
    const token = this.authService.getToken(AuthService.TOKEN_NAME);
    return request.clone({
    setHeaders: {
    Authorization: `Bearer ${token}`
    }
    });
    }
    }
  • requestAccessToken
  •     requestAccessToken(): Observable<any> {
    const refreshToken = this.getToken(AuthService.REFRESH_TOKEN_NAME);
    return this.http.post(`${this.basePath}/auth/refresh`, { refreshToken });
    }

    更新 1

    所以我使用这些来源来编写我的拦截器:
  • https://itnext.io/angular-tutorial-implement-refresh-token-with-httpinterceptor-bfa27b966f57 (Angular 4 解决方案,我相信它依赖于 rxjs 版本)
  • https://github.com/melcor76/interceptors/blob/master/src/app/interceptors/auth.interceptor.ts

  • 更新版本 2

    我已经排除了 refresh来自拦截器范围的请求,现在它正在工作
    感谢@JBNizet

    最佳答案

    我已经从拦截器范围中排除了刷新请求,现在它正在工作。
    我做了一个临时修复,以便看到它以最快的方式工作。

    现在我的 TokenInterceptor 看起来像:

    import { Injectable } from '@angular/core';
    import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
    import { AuthService } from './auth.service';
    import { Observable, BehaviorSubject, Subject } from 'rxjs';
    import { switchMap, take, filter } from 'rxjs/operators';
    @Injectable()
    export class TokenInterceptor implements HttpInterceptor {
    private refreshTokenInProgress = false;
    private refreshTokenSubject: Subject<any> = new BehaviorSubject<any>(null);

    constructor(public authService: AuthService) { }
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (request.url.indexOf('refresh') !== -1) {
    return next.handle(request);
    }

    const accessExpired = this.authService.isAccessTokenExpired();
    const refreshExpired = this.authService.isRefreshTokenExpired();

    if (accessExpired && refreshExpired) {
    return next.handle(request);
    }
    if (accessExpired && !refreshExpired) {
    if (!this.refreshTokenInProgress) {
    this.refreshTokenInProgress = true;
    this.refreshTokenSubject.next(null);
    return this.authService.requestAccessToken().pipe(
    switchMap((authResponse) => {
    this.authService.saveToken(AuthService.TOKEN_NAME, authResponse.accessToken);
    this.authService.saveToken(AuthService.REFRESH_TOKEN_NAME, authResponse.refreshToken);
    this.refreshTokenInProgress = false;
    this.refreshTokenSubject.next(authResponse.refreshToken);
    return next.handle(this.injectToken(request));
    }),
    );
    } else {
    return this.refreshTokenSubject.pipe(
    filter(result => result !== null),
    take(1),
    switchMap((res) => {
    return next.handle(this.injectToken(request))
    })
    );
    }
    }

    if (!accessExpired) {
    return next.handle(this.injectToken(request));
    }
    }

    injectToken(request: HttpRequest<any>) {
    const token = this.authService.getToken(AuthService.TOKEN_NAME);
    return request.clone({
    setHeaders: {
    Authorization: `Bearer ${token}`
    }
    });
    }
    }

    感谢@JBNizet

    关于Angular 8 Intercept 调用刷新 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57637923/

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