У меня проблема с моим компонентом службы аутентификации + в том смысле, что служба, похоже, повторно инициализируется каждый раз, когда я загружаю компонент аутентификации. В моем приложении должен присутствовать поток, заключающийся в том, что корневой компонент-приложение при запуске приложения должен отправить запрос входа в систему, чтобы проверить, аутентифицирован ли текущий сеанс или нет. Этот запрос на вход отправляется из службы авторизации. Служба аутентификации имеет субъект, транслирующий логическое значение, указывающее, аутентифицирован ли пользователь или нет, в зависимости от результата операции входа / выхода.

Это отлично работает, за исключением одного сценария. Если я запускаю приложение на странице аутентификации, ухожу от компонента и возвращаюсь к нему, я не могу получить правильный статус аутентификации (истина / ложь) от службы. Поле (в сервисе) при печати по какой-то причине не определено. Для отладки я даже вставил console.logs в функции ngOnInit, чтобы увидеть, не переинициализировались ли какие-либо компоненты / службы, но ничего.

Вот пример кода, как это выглядит сейчас, app.component.ts (корневой компонент):

constructor(private requestService: RequestService,
              private authService: AuthService) {}

  ngOnInit() {
    console.log("App component init");
    this.requestService.get('http://localhost:8000/api/csrf/')
      .subscribe(
        success => {
          this.authService.login('', '');
        }
    );
  }

Запрос на вход запускается в результате первой проверки CSRF, пока это работает хорошо.

auth.service.ts

@Injectable()
export class AuthService implements OnInit, OnDestroy {
  authenticated: boolean;
  authSubject: Subject<boolean>;

  constructor(private requestService: RequestService) {
    console.log("Auth service constructor");
    this.authSubject = new Subject<boolean>();
  }

  ngOnInit() {
    console.log("Auth service init");
    this.authSubject.subscribe(
      next => {
        this.authenticated = next;
      }
    );
  }

  login(username: string, password: string) {
    console.log("Auth service login");
    this.requestService.post(LOGIN_URL, { username: username, password: password })
      .subscribe(
        next => {
          this.authSubject.next(true);
          console.log("[AuthService] Success logging in.");
        },
        error => {
          console.log("[AuthService] Error logging in.");
        },
        () => {
          console.log("[AuthService] Auth service completed.");
        }
      );
  }

  logout() {
    this.requestService.post(LOGOUT_URL, {})
    .subscribe(
      next => {
        this.authSubject.next(false);
        console.log('[AuthService] Success logging out.');
      },
      error => {
        console.log("[AuthService] Error logging out.");
      },
      () => {
        console.log("[AuthService] Auth service completed.");
      });
  }

  isAuthenticated(): boolean {
    return this.authenticated;
  }

  ngOnDestroy() {
    console.log("Auth service destroyed");
    this.authSubject.unsubscribe();
  }
}

Здесь мы идем, как вы можете видеть выше, я прибег к созданию экземпляра Subject в конструкторе, а не в ngOnInit. Это связано с тем, что при запуске входа в систему из app.component.ts субъект еще не был создан, что вызывает сбой. Но это все еще работает.

auth.component.ts

export class AuthComponent implements OnInit {
  authenticated: boolean;

  constructor(private authService: AuthService) { }

  ngOnInit() {
    console.log("Auth component init");
    this.authService.authSubject.subscribe(
      next => {
        this.authenticated = next;
      }
    );
    this.authenticated = this.authService.isAuthenticated();
    console.log(this.authenticated);
  }

  onLogin(form: NgForm) {
    const username = form.value.username;
    const password = form.value.password;
    this.authService.login(username, password);
  }

  onLogout() {
    this.authService.logout();
  }

Итак, вот где я застрял. Когда я вхожу в систему, я вижу, что я успешно получил ответ и что authenticated = true. Однако, когда я ухожу от представления аутентификации, а затем обратно к нему, получение аутентифицированного значения от authService.isAuthenticated возвращает мне значение «undefined»! Служба существует и не повреждена (я подключился к ngOnDestroy для службы, там ничего не запускается), поэтому я предполагаю, что есть проблема со ссылками или что-то в этом роде, я просто не могу найти ничего в документации, чтобы помочь мне.

Пожалуйста, порекомендуйте.

1
Måns Thörnvik 13 Мар 2018 в 23:17

2 ответа

Лучший ответ

Проблема заключалась в том, что ngOnInit не вызывается для служб angular, поэтому подписка никогда не была активирована в службе аутентификации. Когда я перенес подписку в конструктор сервисов, все заработало!

0
Måns Thörnvik 14 Мар 2018 в 07:25

Попробуйте использовать BehaviorSubject вместо простого Subject. BehaviorSubject будет транслировать последнее значение перед подпиской плюс любые новые значения, тогда как субъект будет транслировать любые новые данные только после того, как вы подпишетесь.

В чем разница между субъектом и поведением субъекта?

0
Daniel W Strimpel 13 Мар 2018 в 20:25