У меня проблема с моим компонентом службы аутентификации + в том смысле, что служба, похоже, повторно инициализируется каждый раз, когда я загружаю компонент аутентификации. В моем приложении должен присутствовать поток, заключающийся в том, что корневой компонент-приложение при запуске приложения должен отправить запрос входа в систему, чтобы проверить, аутентифицирован ли текущий сеанс или нет. Этот запрос на вход отправляется из службы авторизации. Служба аутентификации имеет субъект, транслирующий логическое значение, указывающее, аутентифицирован ли пользователь или нет, в зависимости от результата операции входа / выхода.
Это отлично работает, за исключением одного сценария. Если я запускаю приложение на странице аутентификации, ухожу от компонента и возвращаюсь к нему, я не могу получить правильный статус аутентификации (истина / ложь) от службы. Поле (в сервисе) при печати по какой-то причине не определено. Для отладки я даже вставил 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 для службы, там ничего не запускается), поэтому я предполагаю, что есть проблема со ссылками или что-то в этом роде, я просто не могу найти ничего в документации, чтобы помочь мне.
Пожалуйста, порекомендуйте.
2 ответа
Проблема заключалась в том, что ngOnInit не вызывается для служб angular, поэтому подписка никогда не была активирована в службе аутентификации. Когда я перенес подписку в конструктор сервисов, все заработало!
Попробуйте использовать BehaviorSubject
вместо простого Subject
. BehaviorSubject
будет транслировать последнее значение перед подпиской плюс любые новые значения, тогда как субъект будет транслировать любые новые данные только после того, как вы подпишетесь.
В чем разница между субъектом и поведением субъекта?
Похожие вопросы
Связанные вопросы
Новые вопросы
angular
Вопросы по Angular (не путать с AngularJS), веб-фреймворку от Google. Используйте этот тег для угловых вопросов, которые не относятся к конкретной версии. Для более старой веб-платформы AngularJS (1.x) используйте тег angularjs.