Как избежать нескольких вызовов HttpInterceptor при переходе между RxJS mergeMap? - PullRequest
0 голосов
/ 12 октября 2018

Я использую два токена JWT - токен обновления (истекает через 7 дней) и токен доступа (истекает через 15 минут).Они хранятся в httpOnly куки и могут быть доступны через сервер.Методы обновления подписывают новый токен и сохраняют его в файле cookie.Мне нужно проверить, не истек ли срок действия этих токенов после каждого запроса, например:

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

    constructor(private authService: AuthService, private cookieService: CookieService) { }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
            const expirationToken = this.cookieService.get('tokenexp'); // access token expiration
            const expirationTokenRefresh = this.cookieService.get('tokenrefexp'); // refresh expiration
            
            // refresh token -> access token -> original request
            return of(Number(expirationTokenRefresh) < Date.now()).pipe(
              mergeMap(expire => expire
                ? this.authService.refreshTokenRefresh()
                : of(Number(expirationToken) < Date.now())
              ),
              mergeMap(expire => expire
                ? this.authService.refreshToken()
                : of(true)
              ),
              mergeMap(ok => next.handle(req.clone({ withCredentials: true })))
            );
    }

}

// auth service
refreshToken() {
  return this.http.get(`${BACKEND_URL}/refreshtoken`);
}
refreshTokenRefresh() {
  return this.http.get(`${BACKEND_URL}/refreshtokenref`);
}

Я могу отправить один запрос на обновление токена, а затем еще один запрос на обновление второго токена и, наконец, исходный запрос с обновленными файлами cookie.Таким образом, мне может потребоваться отправить запросы до моего первоначального запроса.

Проблема заключается в следующем: цикл запросов переходит на AuthInterceptor каждый раз, когда делается запрос.Запрос один и два (токены) не должен вызывать AuthInterceptor.

1 Ответ

0 голосов
/ 15 октября 2018

Выполните условную проверку, чтобы пропустить перехватчик, если URL запроса предназначен для токена.

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

    constructor(private authService: AuthService, private cookieService: CookieService) { }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    
            if(req.url===`${BACKEND_URL}/refreshtoken` || req.url ===`${BACKEND_URL}/refreshtokenref`)
              return next.handle(req.clone({ withCredentials: true }))
            
            const expirationToken = this.cookieService.get('tokenexp'); // access token expiration
            const expirationTokenRefresh = this.cookieService.get('tokenrefexp'); // refresh expiration
            
            // refresh token -> access token -> original request
            return of(Number(expirationTokenRefresh) < Date.now()).pipe(
              mergeMap(expire => expire
                ? this.authService.refreshTokenRefresh()
                : of(Number(expirationToken) < Date.now())
              ),
              mergeMap(expire => expire
                ? this.authService.refreshToken()
                : of(true)
              ),
              mergeMap(ok => next.handle(req.clone({ withCredentials: true })))
            );
    }

}

// auth service
refreshToken() {
  return this.http.get(`${BACKEND_URL}/refreshtoken`);
}
refreshTokenRefresh() {
  return this.http.get(`${BACKEND_URL}/refreshtokenref`);
}

Согласитесь с @Xinan, что перехватчик иногда может быть большей проблемой.Создайте свой собственный http сервис, может быть лучше

class HttpService{
   constructoer(private _http:HttpClient)

   preIntercept(url,options){
     this._http.get(tokenUrl).pipe(
       map(res=>{
           //do your stuff
            return {url,options}
        }))

}

get(url,options={}){
    return this.preIntercept(url,options).pipe(
    mergeMap(({url,options})=>this._http.get(url,options))
}

}
...