2 votes

Auth0 et Angular 2 : échec du login et du routage en utilisant le widget de login

Je commence à développer des applications web et j'ai choisi Angular 2 comme framework frontal. Je suis en train d'essayer Auth0 pour l'autorisation des utilisateurs. Le problème est le suivant : J'essaie d'implémenter une fonctionnalité de connexion -> redirection sur la page d'accueil. Immédiatement après l'ouverture du site web, il faut vérifier s'il y a un jeton d'utilisateur dans la base de données. localStorage et ensuite, soit afficher le widget de connexion, soit rediriger vers la page d'accueil. Mais je suis tombé sur un bug très désagréable :

Lorsque je me connecte, la page se rafraîchit et le widget apparaît à nouveau : tokenNotExpired() pour une raison quelconque, revient false . J'appuie pour me connecter à nouveau avec les mêmes informations d'identification - la page se rafraîchit, le widget de connexion disparaît, l'enregistrement indique que tokenNotExpired() est de retour true maintenant, mais ma redirection ne fonctionne toujours pas. Si j'entre maintenant juste mon adresse de base, http://localhost:4200 il me redirige avec succès vers home y tokenNotExpired() renvoie à true .

J'ai essayé de le déboguer mais sans succès - je n'arrive pas à trouver où il échoue.

En fait, je suis certain qu'il y a des problèmes dans la façon dont j'aborde le codage de la fonction de redirection, étant donné mon manque d'expérience. Je vous serais reconnaissant de m'aider, car cela fait un moment que je suis sur cette question.

J'inclus des extraits de mon code en omettant les parties redondantes. J'injecte le service Auth globalement en le bootstrappant dans main.ts.

app.routes.ts :

import {provideRouter, RouterConfig} from "@angular/router";
import {AuthGuard} from './secure/auth.guard';
import {AdminGuard} from "./secure/admin.guard";

import {UserHomeComponent} from "./main/user-cpl/user-home.component";
import {AdminHomeComponent} from "./main/admin-cpl/admin-home.component";
import {LoginPageComponent} from "./login/login-page.component";

const APP_ROUTES: RouterConfig = [

  { path: 'home', canActivate: [AuthGuard],
    children: [
      { path: '', component: UserHomeComponent },
      { path: 'admin', component: AdminHomeComponent, canActivate: [AdminGuard] },
      ] },
  { path: 'login', component: LoginPageComponent },
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: '**', redirectTo: 'home', pathMatch: 'full' }
];

export const APP_ROUTES_PROVIDER = [
  provideRouter(APP_ROUTES)
];

login-page.component.ts :

import {Component, OnInit} from '@angular/core';
import {ROUTER_DIRECTIVES, Router} from '@angular/router';
import {Auth} from '../secure/auth.service';

@Component({
  moduleId: module.id,
  selector: 'login-page-component',
  template: `
    <router-outlet></router-outlet>  
  `,
  directives: [ROUTER_DIRECTIVES]
})
export class LoginPageComponent implements OnInit {

  constructor(private auth: Auth, private router: Router) {
  }

  ngOnInit():any {
    console.log('LOGGED IN - ' + this.auth.loggedIn());
    if (this.auth.loggedIn()) {
      if (this.auth.isAdmin()) {
        this.router.navigate(['/home/admin']);
      } else if (!this.auth.isAdmin()) {
        this.router.navigate(['/home']);
      }

    } else {
      this.auth.login();
    }
  }
}

auth.service.ts :

import {Injectable} from '@angular/core';
import {tokenNotExpired} from 'angular2-jwt';

declare var Auth0Lock: any;

@Injectable()
export class Auth {
  // Configure Auth0
  lock = new Auth0Lock('omitted', 'omitted', {
    closable: false
  });

  //Store profile object in auth class
  userProfile: any;

  constructor() {
    // Set userProfile attribute if already saved profile
    this.userProfile = JSON.parse(localStorage.getItem('profile'));

    // Add callback for lock `authenticated` event
    this.lock.on("authenticated", (authResult) => {
      localStorage.setItem('id_token', authResult.idToken);

      // Fetch profile information
      this.lock.getProfile(authResult.idToken, (error, profile) => {
        if (error) {
          // Handle error
          alert(error);
          return;
        }

        localStorage.setItem('profile', JSON.stringify(profile));
        this.userProfile = profile;
      });
    });
  }

  login() {
    this.lock.show({
      callbackUrl: 'http://localhost:4200/home'
    });
  }

  logout() {
    localStorage.removeItem('profile');
    localStorage.removeItem('id_token');
    this.userProfile = undefined;
  }

  loggedIn() {
    return tokenNotExpired();
  }

  isAdmin() {
    return this.userProfile && this.userProfile.app_metadata
      && this.userProfile.app_metadata.roles
      && this.userProfile.app_metadata.roles.indexOf('admin') > -1;
  }
}

auth.guard.ts :

import {Injectable} from '@angular/core';
import {Router, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
import {CanActivate} from '@angular/router';
import {Auth} from './auth.service';

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(private auth: Auth, private router: Router) {
  }

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    if (this.auth.loggedIn()) {
      console.log('AUTH GUARD PASSED');
      return true;
    } else {
      console.log('BLOCKED BY AUTH GUARD');
      this.router.navigate(['/login']);
      return false;
    }
  }
}

admin.guard.ts :

import {Injectable} from '@angular/core';
import {Router, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
import {CanActivate} from '@angular/router';
import {Auth} from './auth.service';

@Injectable()
export class AdminGuard implements CanActivate {

  constructor(private auth: Auth, private router: Router) {}

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    if (this.auth.isAdmin()) {
      return true;
    } else {
      return false;
    }
  }
}

5voto

Kabir Roy Points 740

Vous devez définir redirect: false dans la configuration puisqu'il s'agit d'une application à page unique. Sinon, Auth0 effectuera un appel GET à l'application redirectUrl . Cet appel empêche votre authenticated l'événement de se déclencher. Ainsi, dans votre auth.service.ts fichier :

lock = new Auth0Lock('omitted', 'omitted', {
  closable: false,
  auth: { // <--- mind this nesting
    redirect: false
  }
});

Cela invoquera l'événement "authentifié" dans le service lors de la connexion. Vous souhaitez probablement aussi rediriger l'utilisateur une fois la connexion effectuée. Ainsi, dans le callback invoquer this._router.navigate(['path']) . N'oubliez pas de import { Router } from 'angular/router' et de créer une instance dans le constructeur : constructor(private _router: Router) {} .

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