Почему на моем isLoggedIn наблюдаема ошибка «единовременно, впервые»? - PullRequest
0 голосов
/ 20 апреля 2020

Я знаю, в это трудно поверить, но Наблюдаемые объекты довольно хитры, и я не на 100% понимаю их. : -)

Учитывая этот код:

  private currentUserSubject: BehaviorSubject<User>;
  public currentUser: Observable<User>;
  private loggedIn = new BehaviorSubject<boolean>(this.tokenIsValid());

  ...

  get isLoggedIn(): Observable<boolean> {
    this.loggedIn.next(this.tokenIsValid());
    return this.loggedIn.asObservable();
  }

  private tokenIsValid(): boolean {
    let currentUser: User = this.currentUserValue;
    if (currentUser) {
      const token = currentUser.token;
      const tokenInfo = this.getDecodedAccessToken(token);
      if (Date.now() <= tokenInfo.exp * 1000) {
        return true;
      }
    }
    return false;
  }

  private getDecodedAccessToken(token: string): any {
    try {
      return jwt_decode(token);
    } catch (Error) {
      return null;
    }
  }

Почему isLoggedIn сообщает true, когда это должно быть не один раз (первый раз после выхода из системы), а затем работает идеально после этого?

Вот последовательность:

  1. Я вхожу в JWT с хорошим, проверяемым 15-секундным тайм-аутом.
  2. Я go к защищенному ресурсу и вижу его.
  3. Я подожду еще 15 секунд до истечения срока действия JWT
  4. I go к другому защищенному ресурсу, и я его вижу.
  5. I go назад к начальный защищенный ресурс, и я не вижу его.
  6. Я go снова возвращаюсь ко второму защищенному ресурсу, и я не вижу его.

И под "видеть это" я имею в виду, что я не запрещен мой AuthGuard, чтобы увидеть страницу.

Мой вопрос: почему ошибка только в первый раз?

ADDED: Вот конструктор для класса AuthenticationService, если это помогает:

constructor(private httpClient: HttpClient) {
    this.currentUserSubject = new BehaviorSubject<User>(JSON.parse(localStorage.getItem(this.currUser)));
    this.currentUser = this.currentUserSubject.asObservable();
  }

1 Ответ

1 голос
/ 21 апреля 2020

Я не понимаю полный контекст вашего вопроса, но вижу потенциальную проблему в этом фрагменте кода

  get isLoggedIn(): Observable<boolean> {
    this.loggedIn.next(this.tokenIsValid());
    return this.loggedIn.asObservable();
  }

Здесь, кажется, вы пытаетесь сделать 2 вещи

  1. Сначала вы уведомляете, если пользователь вошел в систему с this.loggedIn.next(this.tokenIsValid())
  2. Затем вы возвращаете Subject (как Observable), используемый для передачи всем заинтересованным сторонам вышеуказанного уведомления

Дело в том, что каждая сторона (например, ваш AuthGuard), которая хочет получать уведомления, когда что-то происходит first , должна подписаться на Observable, в котором она заинтересована, и только затем он получает любое уведомление, когда выходит Наблюдаемая.

Это означает, что вы должны найти способ для вашей заинтересованной стороны сначала подписаться на loggedIn как Наблюдаемая с чем-то вроде

  get isLoggedIn(): Observable<boolean> {
    return this.loggedIn.asObservable();
  }

и только тогда найдите подходящее место, чтобы loggedIn испустить что-либо через this.loggedIn.asObservable().

Если, скорее, смысл в том, что вы хотите получать уведомление о событии, даже если оно произошло быть Для подписки вы должны использовать ReplySubject, а не BehaviorSubject.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...