web-dev-qa-db-fra.com

Empêcher le routage dans Angular lorsque l'utilisateur modifie manuellement l'URL dans l'onglet du navigateur

Je suis coincé dans un problème qui se produit lorsque l'utilisateur modifie manuellement l'itinéraire dans l'onglet du navigateur et appuie sur Entrée. Cela oblige mon ui-router/angular2-router à naviguer vers l'état entré par l'utilisateur. Je souhaite empêcher cela et autoriser le routage uniquement via le flux que j'ai mis en œuvre par des clics sur les boutons de mon site Web.

13
Vishal Gulati

C'est 2018! Angular 5 est ici et est donc la solution à ce problème. BAMM its CanActivate Interface qu'une classe peut implémenter pour être un garde décidant si une route peut être activée.

Nous pouvons ajouter cette fonctionnalité et empêcher l'accès à certains de nos itinéraires en fonction des conditions que nous définissons. Un service pour par exemple AuthGuard qui implémente l'interface CanActivate et définit la méthode canActivate peut être ajouté à la configuration de l'itinéraire.

class Permissions {
  canGoToRoute(user: UserToken, id: string): boolean {
    return true;
  }
}

@Injectable()
class AuthGuard implements CanActivate {
  constructor(private permissions: Permissions, private currentUser: UserToken) {}

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean>|Promise<boolean>|boolean {
    return this.permissions.canGoToRoute(this.currentUser, route.params.id);
  }
}

Si nous avons une route à laquelle nous voulons protéger l'accès contre certaines conditions, nous ajoutons le gardien comme suit:

const appRoutes: Routes = [
  { path: 'crisis-center', component: CrisisListComponent },
  {
    path: 'heroes',
    canActivate: [AuthGuard],
    component: HeroListComponent,
    data: { title: 'Heroes List' }
  },
  { path: '',
    redirectTo: '/heroes',
    pathMatch: 'full'
  },
  { path: '**', component: PageNotFoundComponent }
];

Ici, la route heroes et tous ses enfants ont une couche de garde dessus. Par conséquent, sur la base de la valeur booléenne renvoyée par le service AuthGuard, l'utilisateur sera autorisé ou refusé l'accès à cette route.

7
Vishal Gulati

Vous pouvez importer un routeur dans le constructeur d'un garde. Cette instance de routeur aura l'URL actuelle. ActivatedRouteSnapshot et RouterStateSnapshot dans canActivate contiendront l'URL à laquelle l'utilisateur tente d'accéder.

L'exemple ci-dessous empêche les utilisateurs d'accéder directement à un itinéraire à partir d'une page extérieure.

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class DirectAccessGuard implements CanActivate {
  constructor(private router: Router) {}

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    // If the previous URL was blank, then the user is directly accessing this page
    if (this.router.url === '/') {
      this.router.navigate(['']); // Navigate away to some other page
      return false;
    }
    return true;
  }
}

Ajoutez cette garde à votre module de routage

{ path: 'signup/:type/:step', component: SignupComponent, canActivate: [DirectAccessGuard] }
3
Scott Reed

Le $stateChangeStart événement est le bon endroit pour gérer cela. Cet événement se déclenche lorsque vous essayez de naviguer vers un URL. À ce stade, vous pouvez vérifier si l'utilisateur est authentifié et sinon, le renvoyer à la connexion.

Vous connecteriez l'événement comme ceci:

angular
  .module('myApp')
  .run(function ($rootScope, $state, authFactory) {
    $rootScope.$on('$stateChangeStart', function () {
      //if user is not logged in
      if(!authFactory.isAuthed()){ 
        $state.go('login')
      }
    })
  });

J'espère que ça aide.

0
M. Junaid Salaat