Angular универсальная начальная навигация - PullRequest
0 голосов
/ 17 июня 2020

Я использую angular universal в своем проекте, а для своей аутентификации я использую токен доступа с продолжительностью 15 минут и токен refre sh с продолжительностью 24 часа. когда я получаю приложение с сервера, я разрешаю пользователя из api, а затем загружаю (accesToken и refreshToken - это файлы cookie, которые получает сервер). Теперь я хочу, чтобы сервер перешел на страницу входа в систему, если токен refre sh недействителен или истек. Я обрабатываю все эти ошибки в своем перехватчике. Если я получаю 401, я использую токен refre sh, чтобы получить новый токен доступа и повторно отправить исходный запрос, но если запрос токена refre sh завершится неудачно, я хочу вывести пользователя из системы. код перехватчика:

const InterceptorSkipHeader = 'X-Skip-Interceptor';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  private refreshTokenInProgress = false;
  private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);

  constructor(
    private cookies: CookiesService,
    private sb: AppSandbox, private apiService: ApiService, private authService: AuthService, private router: Router) { }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (req.headers.has(InterceptorSkipHeader)) {
      const headers = req.headers.delete(InterceptorSkipHeader);
      return next.handle(req.clone({ headers }));
    }

    const token = this.authService.accessToken;
    return next.handle(
      token !== null
        ? req.clone({ setHeaders: { 'authorization': `Bearer ${token}` } })
        : req
    ).pipe(catchError((err) => {
      if (err instanceof HttpErrorResponse) {
        if (err.status !== 401) {
          return throwError(err);
        }
        if (this.refreshTokenInProgress) {
          return this.refreshTokenSubject.pipe(filter(result => result != null), take(1), switchMap((result) => {
            return next.handle(req.clone({ setHeaders: { 'authorization': `Bearer ${result}` } }));
          }));
        } else {
          this.refreshTokenInProgress = true;
          this.refreshTokenSubject.next(null);

          const refreshToken = this.authService.refreshToken;


          return this.apiService.sendRequest(EHttpMethod.GET, EApiEndpoints.REFRESH_AUTH_TOKEN,
            null, null, new HttpHeaders()
              .set('X-Skip-Interceptor', 'true').set('authorization', `Bearer ${refreshToken}`)).pipe(
                switchMap((res) => {
                  this.authService.setNewAccessToken(res.accessToken);
                  this.refreshTokenInProgress = false;
                  this.refreshTokenSubject.next(res.accessToken);

                  return next.handle(res.accessToken !== null
                    ? req.clone({ setHeaders: { 'authorization': `Bearer ${res.accessToken}` } })
                    : req);
                }), catchError((error) => {
                  this.refreshTokenInProgress = false;
                  this.sb.userLogout();
                  return throwError(error);
                })
              );
        }
      }
    }));
  }
}

последняя ошибка catchError должна обрабатывать именно этот случай, но почему-то я получаю только ошибку на сервере, и никакой навигации не происходит (приложение зависает).

...