services navigationend example change angular angular2-routing angular2-guards

navigationend - Angular2: Global Guard(el usuario debe estar conectado siempre)



singleton angular 4 service (2)

Creo que lo hago de una manera mucho más lógica. Supongo que es una opinión. Separa mi aplicación por secured pages y public pages . Yo uso plantillas para cada conjunto. Entonces, public component y secure component ponen el guard sobre la secure template .

Asegúrese de agregar [Guard] a la ruta completa que necesita protección.

Entonces, cuando aseguro una ruta, agrego los padres a app.routing.ts

const APP_ROUTES: Routes = [ { path: '''', redirectTo: ''/home'', pathMatch: ''full'', }, { path: '''', component: PublicComponent, data: { title: ''Public Views'' }, children: PUBLIC_ROUTES }, { path: '''', component: SecureComponent, canActivate: [Guard], data: { title: ''Secure Views'' }, children: SECURE_ROUTES } ]; export const routing = RouterModule.forRoot(APP_ROUTES);

Asegúrate de que esta línea se note,

{ path: '''', component: SecureComponent, canActivate: [Guard], data: { title: ''Secure Views'' }, children: SECURE_ROUTES }

Entonces creo 2 diseños

/ público / todos los componentes públicos

/public/public.routes.ts

/ seguro / todos los componentes seguros

/secure/secure.routes.ts

Rutas seguras

Tenga en cuenta que estas rutas no necesitan Guard ahora porque la maneja la plantilla principal.

export const SECURE_ROUTES: Routes = [ { path: '''', redirectTo: ''overview'', pathMatch: ''full'' }, { path: ''items'', component: ItemsComponent }, { path: ''overview'', component: OverviewComponent }, { path: ''profile'', component: ProfileComponent }, ];

Principales rutas en app.routing.ts

const APP_ROUTES: Routes = [ { path: '''', redirectTo: ''/home'', pathMatch: ''full'', }, { path: '''', component: PublicComponent, data: { title: ''Public Views'' }, children: PUBLIC_ROUTES }, { path: '''', component: SecureComponent, canActivate: [Guard], data: { title: ''Secure Views'' }, children: SECURE_ROUTES } ]; export const routing = RouterModule.forRoot(APP_ROUTES);

Y en el directorio / diseños, creo un diseño que es

/layouts/secure.component.ts

/layouts/secure.component.html

/layouts/public.component.ts

/layouts/public.component.html

Todo se enruta a través del diseño public o secure y [Guard] está seguro.

Luego manejo la autenticación con un token en el almacenamiento local.

@Injectable() export class Guard implements CanActivate { constructor(protected router: Router, protected auth: Auth ) {} canActivate() { if (localStorage.getItem(''access_token'')) { // logged in so return true return true; } // not logged in so redirect to login page this.router.navigate([''/home'']); return false; } }

Una vez que configuro mi aplicación de esta manera, puse todas las rutas que deben estar seguras en el directorio seguro y las rutas públicas en público. Luego creo sus rutas en el archivo public.routes.ts o en el archivo secure.routes.ts que están en su directorio respectivo.

Estoy construyendo una aplicación donde no hay acceso para usuarios no autenticados.

Escribí un LoggedInGuard , pero ahora tengo que agregar canActivate: [LoggedInGuard] a cada ruta dentro de la configuración de mi enrutador (excepto el LoginComponent ).

¿Hay una mejor manera de hacer que esto funcione?

El diseño de mi archivo / módulo se ve así:

app/ AppModule AppRoutingModule AppComponent authentication/ AuthenticationModule AuthenticationRoutingModule LoginComponent contacts/ ContactsModule ContactsRoutingModule ContactListComponent users/ UsersModule UsersRoutingModule UserEditComponent ...

Tal vez sea posible crear dos espacios de enrutamiento separados (uno para iniciar sesión, otro para el resto de la aplicación) y aplicar el protector solo al resto de la parte de la aplicación .

Espero que haya una solución simple.

¡Gracias por adelantado!


Pude proporcionar un conjunto de protecciones globales que abarcaban múltiples módulos al mover las guardias a un detector de eventos de enrutador.

Para que el detector de eventos active todas las solicitudes, lo inserté en el componente de aplicación.

Tenga en cuenta que, en ambos ejemplos a continuación, aún puede agregar guardias personalizados para rutas individuales, y eso seguirá funcionando.

Sin guardias

Puede eliminar el uso de guardias y, en su lugar, implementar la lógica directamente en el detector de eventos.

import { Component, OnInit } from ''@angular/core''; import { Router, RoutesRecognized } from ''@angular/router''; import { Observable } from ''rxjs/Observable''; import ''rxjs/add/operator/filter''; // I use a service to keep track of the authentication ticket. // Replace this with whatever mechanism you use. import { AuthenticationService } from ''./_services/index''; @Component({ selector: ''app-root'', templateUrl: ''./app.component.html'', styleUrls: [''./app.component.css''] }) export class AppComponent implements OnInit { constructor( private router: Router, private authService: AuthenticationService ) {} ngOnInit() { this.router.events .filter(event => event instanceof RoutesRecognized) .subscribe((event: RoutesRecognized) => { const url = event.urlAfterRedirects; // Public URLs don''t need any kind of authorization. if (url === ''/public'' || url.startsWith(''/public/'') || url.startsWith(''/public?'')) { return; } // Everything else must be authenticated. if (!this.authService.isAuthenticated()) { // Allow for the login page to redirect back to the originally // requested page. this.router.navigate([''/public/login''], { queryParams: { returnUrl: state.url } }); } }); } }

Las solicitudes que se pasan a cualquier subpágina de /public pasarán independientemente, pero cualquier otra solicitud debe tener autenticación, o se redirigirá a /public/login .

Tenga cuidado de que la página de redirección no se encuentre en el área protegida, de lo contrario, el enrutador ingresará un bucle infinito.

Con guardias

La implementación a continuación muestra cómo reutilicé las guardias existentes. Esto es solo si necesita conservarlos, o si hace que su código sea más limpio.

import { Component, OnInit } from ''@angular/core''; import { Router, ActivatedRoute, RoutesRecognized, CanActivate } from ''@angular/router''; import { Observable } from ''rxjs/Observable''; import ''rxjs/add/operator/filter''; import ''rxjs/add/operator/map''; import ''rxjs/add/operator/mergeMap''; // Reused guards. import { AdminGuard, AuthGuard } from ''./_guards/index''; @Component({ selector: ''app-root'', templateUrl: ''./app.component.html'', styleUrls: [''./app.component.css''] }) export class AppComponent implements OnInit { constructor( private route: ActivatedRoute, private router: Router, private adminGuard: AdminGuard, private authGuard: AuthGuard ) {} ngOnInit() { this.router.events .filter(event => event instanceof RoutesRecognized) .subscribe((event: RoutesRecognized) => { // Public pages don''t require authentication. if (this.isSubPage(event, ''/public'')) { return; } // All other requests MUST be done through an // authenticated connection. The guard performs // the redirection for us. if (!this.callCanActivate(event, this.authGuard)) { return; } // Administration pages require additional restrictions. // The guard performs the redirection for us. if (this.isSubPage(event, ''/admin'')) { if (!this.callCanActivate(event, this.adminGuard)) { return; } } }); } callCanActivate(event: RoutesRecognized, guard: CanActivate) { return guard.canActivate(this.route.snapshot, event.state); } isSubPage(event: RoutesRecognized, parent: string) { const url = event.urlAfterRedirects; return (url === parent || url.startsWith(parent + ''/'') || url.startsWith(parent + ''?'')); } }

Este ejemplo es el mismo que el anterior, pero con protección adicional para el área /admin , lo que garantiza que el usuario también tenga permisos administrativos.