Перенаправление в случае обновления 401 на JWT - PullRequest
1 голос
/ 20 марта 2020

В настоящее время я разрабатываю приложение Angular 9 с аутентификацией JWT на бэкэнде.

Я следовал учебному руководству, которое помогло мне создать HTTPInterceptor для обновления sh моего JWT, если оно истек срок действия, используя токен refre sh. Мои токены находятся в cookie-файлах, установленных на сервере, и, следовательно, их не нужно добавлять в заголовки.

У меня есть следующий код перехватчика:

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<any> {
  console.log("Intercepted!");
  return next.handle(req).pipe(
    catchError((error: HttpErrorResponse) => {
      console.log("Error seen");
      if (error && error.status === 401) {
        // 401 errors are most likely going to be because we have an expired token that we need to refresh.
        if (this.refreshing) {
          console.log("Already refreshing");
          // If refreshTokenInProgress is true, we will wait until refreshTokenSubject has a non-null value
          // which means the new token is ready and we can retry the request again
          return this.refreshTokenSubject.pipe(
            filter(result => result !== null),
            take(1),
            switchMap(() => next.handle(req))
          );
        } else {
          this.refreshing = true;

          // Set the refreshTokenSubject to null so that subsequent API calls will wait until the new token has been retrieved
          this.refreshTokenSubject.next(null);

          return this.authService.refreshToken().pipe(
            switchMap((success: boolean) => {
              this.refreshTokenSubject.next(success);
              return next.handle(req);
            }),
            // When the call to refreshToken completes we reset the refreshTokenInProgress to false
            // for the next time the token needs to be refreshed
            finalize(() => this.refreshing = false)
          );
        }
      } else {
        return throwError(error);
      }
    })
  );
}

Это просто выполняет работу нормально при обновлении JWT, но у меня есть другая проблема, на которую я не могу найти ответ.

Когда мой токен refre sh истек / отсутствует, я бы хотел, чтобы мой маршрутизатор перенаправил на страница авторизации. По сути, это происходит, когда 401 возвращается по пути /api/token/refresh. Как вы можете видеть, я добавил несколько журналов, и при получении от защищенного URL-адреса это вывод:

sendGet
to: /api/test
authconfig.interceptor.ts:27 Intercepted!
GET https://localhost:8000/api/test 401
authconfig.interceptor.ts:30 Error seen
auth.service.ts:43 Refreshing token using refreshtoken from AuthService.
authconfig.interceptor.ts:27 Intercepted!
VM1101:1 GET https://localhost:8000/api/token/refresh 401
authconfig.interceptor.ts:30 Error seen
authconfig.interceptor.ts:34 Already refreshing

Перехватчик думает, что он все еще обновляется, потому что он никогда не получал правильный ответ от сервера при попытке обновить sh токен. Который, если бы это был второй GET, был бы подходящим ответом, и я не знаю, как провести различие между ними. Я подумал о добавлении функции для проверки того, что я все еще вошел в систему с помощью GETting из /api/token/refresh, но она, очевидно, просто перехватывается и удерживается.

Что такое умный способ go сделать это? Я думал о том, что в куки-файлах httponly нет маркера refre sh, поэтому клиент может просто проверить, есть ли он еще там, и прийти к выводу, что он больше не авторизован, но мне это кажется недостатком безопасности.

1 Ответ

0 голосов
/ 21 марта 2020

Я смог решить эту проблему самостоятельно. Проверяя, находится ли URL-адрес для обновления токена в запросе, прежде чем поместить его в очередь, можно обнаружить, что токен refre sh отсутствует. В конце концов, эта последовательность событий произойдет, только если запрос к пути обновления токена вернет 401, указывая, что токена нет.

Если путь запроса содержит URL-адрес для обновления токена, мы можем перенаправить.

...