2 votes

Angular - Résolution des données Observable avant canActivate

Je travaille sur une application web utilisant Angular et j'ai rencontré un problème. Il y a un service d'authentification qui permet de se connecter à un utilisateur. J'envoie une requête à au serveur avec les informations d'identification et j'attends une réponse. Le problème est que je J'essaie de naviguer du composant de connexion au composant d'accueil. de la réponse

  login(formValues) {
    this.auth.logInUser(formValues.username, formValues.password)
    .subscribe(response =>{
      if(!response){
        this.invalidLogin=true;
      } else {
        this.router.navigate(['stream']);
      }
    })
  }

Mais tous les autres composants ont un canActivateGuard qui vérifie si l'utilisateur actuel est connecté (les données que j'attends du serveur).

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;
  }

Existe-t-il un moyen de résoudre le problème avant que la vérification de la fonction canActivate ne soit effectuée ? Existe-t-il d'autres solutions ?
Tout autre conseil sur la façon de protéger les composants serait le bienvenu :D

0 votes

Veuillez vérifier la réponse mise à jour :)

1voto

Rukshan Dangalla Points 750

J'ai rencontré le même problème et voici comment je l'ai résolu.

Vous pouvez retourner Observable<boolean> de la méthode canActivate. Essayez de renvoyer un Observable au lieu d'un booléen pur.

Une autre option est de retourner la promesse.

Jetez un coup d'œil à CanActivate .

Voici l'exemple de code :

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));
    }
}

0 votes

Comment contrôler si l'observable échoue ou si l'utilisateur n'est pas authentifié ? La page reste en suspens / ne fait rien

0voto

willmaz Points 792

Vous pouvez utiliser obervable , voici un exemple :

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;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X