Где в Angular время жизни запроса для обновления токена JWT

Я все еще новичок в Angular. Я хочу обновить токен доступа, но не знаю, где это сделать.

Я знаю о guards andinterceptors. Где лучше всего это сделать? Есть ли компромиссы, которые я должен принять во внимание?

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

Любой совет будет принят во внимание.


ОБНОВЛЕНИЕ
Я знаю «как», мне нужно понять, почему. Где правильное место для обновления?

Задача охранника — просто проверить, вошел ли пользователь в систему, и, если нет, перенаправить на страницу входа.

Если срок действия токена обновления истек, я считаю, что охранник должен вернуть false для canActivate(ActivatedRouteSnapshot, RouterStateSnapshot), потому что пользователь, хотя и прошел проверку подлинности, больше не имеет текущего гранта.

Вот почему я склоняюсь к тому, чтобы поставить его в охрану. Но большинство примеров, в том числе превосходный приведенный ниже, показывают обновление в перехватчике. Несомненно, к тому времени это уже очень поздно в цикле запроса? Что мне здесь не хватает - это только вопрос стиля, или есть еще цикл запроса angular, который я должен учитывать?

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
1
0
189
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать HttpInterceptor. Поскольку каждый вызов API проходит через перехватчик, вы можете проверить, действителен ли токен, и продолжить вызов API.

Если срок действия токена истек, покажите предупреждение toastr и предотвратите дальнейшие вызовы API.

Для получения дополнительной информации об использовании перехватчика посетите эти 10 способов использования перехватчиков и Угловой 7 Перехватчик JWT.

Complete Code:

http-interceptor.service.ts

import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { SessionService } from './session.service';
import { Router } from '@angular/router';
import { throwError } from 'rxjs';

declare var toastr;

@Injectable({
  providedIn: 'root'
})
export class HttpInterceptorService implements HttpInterceptor {

  constructor(private router: Router, private sessionService: SessionService) { }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    var token = this.sessionService.getToken();
    if (token != null && this.sessionService.isTokenExpired()) {
      this.sessionService.logOut()
      toastr.warning("Session Timed Out! Please Login");
      this.router.navigate(['/login'])
      return throwError("Session Timed Out")
    } else {

      const authRquest = req.clone({
        setHeaders: {
          Authorization: 'Bearer ' + token
        }
      })
      return next.handle(authRquest)
        .pipe(
          tap(event => {
          }, error => {
          })
        )
    }

  }
}

app.module.ts

 providers: [
    {
        provide: HTTP_INTERCEPTORS,
        useClass: HttpInterceptorService,
        multi: true
      }
   ]

сеанс-service.ts

  getToken(): string {
    return localStorage.getItem('userToken');
  }

  getTokenExpirationDate(token: string): Date {
    token = this.getToken()
    const decoded = jwt_decode(token);

    if (decoded.exp === undefined) return null;

    const date = new Date(0);
    date.setUTCSeconds(decoded.exp);
    return date;
  }

  isTokenExpired(token?: string): boolean {
    if (!token) token = this.getToken();
    if (!token) return true;

    const date = this.getTokenExpirationDate(token);
    if (date === undefined) return false;
    return !(date.valueOf() > new Date().valueOf());
  }

  logOut(loginType?: string) {
    localStorage.removeItem('isLoggedin');
    localStorage.removeItem('userRole');

  }

Спасибо за этот очень хороший и очень полный пример! Однако мне интересно, лучше ли это делать в перехватчике, как вы показали, или в охраннике. Хотя я новичок в angular, моя интуиция подсказывает мне, что охранник — лучшее место, потому что именно там вы решаете, активировать ли маршрут. Но большинство примеров похожи на этот, и я не уверен, что это проблема стиля, или я чего-то не понимаю...

lonix 18.06.2019 10:24
Interceptor это место, чтобы сделать это. В Guard мы фактически оцениваем, имеет ли пользователь (вошедший в систему) доступ к маршруту. И Guard — это место для проверки маршрутизации, оно не связано с HTTP-вызовами, а токены связаны с Http-вызовами, которые должны обрабатываться в interceptors
Adrita Sharma 18.06.2019 10:27

Ооо... теперь я понимаю. Таким образом, охранник должен только проверить, является ли пользователь разрешается для доступа к этому маршруту - действительно ли он вошел в систему или нет, на этом этапе не имеет значения. Спасибо за разъяснения! :)

lonix 18.06.2019 10:35

Честно говоря, я проверил репо на ту ссылку, которую вы разместили, и это подтвердило мои подозрения. Я не уверен, что охрана - лучшее место. Он не выполняет какую-либо операцию ACL — он проверяет, вошел ли пользователь в систему, и, если нет, перенаправляет на страницу входа. Если срок действия токена обновления истек, то ответ на canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) должен быть ложным. Я считаю, что охрана - это место, где можно это сделать, но я новичок, поэтому могу ошибаться.

lonix 18.06.2019 10:56

Я хочу оставить вопрос открытым еще немного, чтобы получить больше идей. Вы, вероятно, правы, но я хочу посмотреть, какие компромиссы упоминают люди.

lonix 18.06.2019 10:57

Конечно.. Я поделился всем, что знаю. Может быть я не прав или прав частично, я работал над несколькими проектами в двух организациях, и везде используется подход interceptor

Adrita Sharma 18.06.2019 10:59

Ваш пример по-прежнему великолепен, независимо от того, идет ли код в охрану или перехватчик, я буду его использовать! :-)

lonix 18.06.2019 11:02

Спасибо. Это скопировано из живого проекта :)

Adrita Sharma 18.06.2019 11:03

Другие вопросы по теме