Angular - Разрешение наблюдаемых данных перед canActivate
Я работаю над веб-приложением, использующим Angular, и столкнулся с проблемой. Существует служба аутентификации, которая регистрирует пользователя. Я отправляю запрос на сервер с учетными данными и жду ответа. Проблема в том, что я пытаюсь перейти от компонента входа в систему к домашнему компоненту В подписке ответил
login(formValues) {
this.auth.logInUser(formValues.username, formValues.password)
.subscribe(response =>{
if(!response){
this.invalidLogin=true;
} else {
this.router.navigate(['stream']);
}
})
}
Но у каждого другого компонента есть canActivateGuard, который проверяет, вошел ли текущий пользователь в систему (данные, которые я жду от сервера).
export const appRoutes: Routes = [
{path: 'login', resolve: LiveStreamResolver, component: LoginComponent},
{path: 'reports', component: ReportsComponent, resolve: LiveStreamResolver, canActivate: [AuthGuardService]},
{path: 'calendar', component: CalendarComponent, resolve: LiveStreamResolver, canActivate: [AuthGuardService]},
{path: 'stream', component: LiveStreamComponent},
{path: '', redirectTo: 'login', pathMatch: 'full'}
];
constructor(public auth: AuthenticationService) { }
canActivate(): boolean {
return !!this.auth.currUser;
}
Есть ли способ разрешить проблему до проверки canActivate? Есть ли другие решения, может быть?
Любые другие советы о том, как охранять компоненты будут приветствоваться:D
2 ответа
Я столкнулся с той же проблемой, и вот как я решил ее.
Вы можете вернуться Observable<boolean>
из метода canActivate. Попробуйте вернуть Observable вместо чистого логического значения.
Кроме того, другой вариант, вы можете вернуть обещание.
Посмотрите на CanActivate.
Вот пример кода:
AuthenticationService
@Injectable()
export class AuthenticationService {
private isAuthenticatedSubject = new ReplaySubject<boolean>(0);
public isAuthenticated = this.isAuthenticatedSubject.asObservable();
constructor() { }
/* Call this method once user successfully logged in. It will update the isAuthenticatedSubject*/
setAuth() {
this.isAuthenticatedSubject.next(true);
}
}
AuthgaurdService
@Injectable()
export class AuthgaurdService implements CanActivate {
constructor(
private router: Router,
private authService: AuthenticationService) { }
canActivate(route: ActivatedRouteSnapshot,state: RouterStateSnapshot): Observable<boolean> {
// this will return Observable<boolean>
return this.authService.isAuthenticated.pipe(take(1));
}
}
Вы можете использовать obervable, вот пример:
constructor(private authService: AuthService, private router: Router) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean {
if (this.authService.isLoggedIn()) {
return true;
}
this.router.navigate(['/login']);
return false;
}