Búsqueda de sitios web

typescript - Angular2 Router - ¿Alguien sabe cómo usar canActivate en app.ts para que pueda redirigir a la página de inicio si no ha iniciado sesión?


Router de Angular2 - ¿Alguien sabe cómo usar canActivate en app.ts para que pueda redirigir a la página de inicio si no está conectado?

Estoy usando TypeScript y Angular 2.

Intento actual bajo mi constructor en mi archivo app.ts:

   canActivate(instruction) {           
               console.log("here - canActivate");
               console.log(instruction);

               this.router.navigate(['Home']);  
   }

Actualmente no le da. ¿Alguna idea de por qué?

Respuesta #1

Entonces, la documentación parece que esto es lo que exporta.

export CanActivate(options : CanActivateAnnotation) : (hook: (next: ComponentInstruction, prev: ComponentInstruction) =>
                     Promise<boolean>| boolean) => ClassDecorator

@CanActivate((next, prev) => {
      // This must prove to be true for the component @ this route to load
      if(next.urlPath != '/Login'){ 
         return Promise.resolve(this._authService.getIsAuth() 
         && localStorage.getItem('authToken')
      }
      /*
       If CanActivate returns or resolves to false, the navigation is 
       cancelled. If CanActivate throws or rejects, the navigation is also
       cancelled. If CanActivate returns or resolves to true, navigation 
       continues, the component is instantiated, and the OnActivate hook of 
       that component is called if implemented.
      */
   }
);

Al final de la documentación de Angular2 agregan este fragmento: exportado desde angular2/router https://angular.io/docs/ts/latest/api/router/CanActivate-decorator.html

Entonces, si estás buscando hacer una redirección desde un nivel superior, no usarías el decorador CanActivate, harías lo siguiente.

import {Directive, Attribute, ElementRef, DynamicComponentLoader} from 'angular2/core';
import {Router, RouterOutlet, ComponentInstruction} from 'angular2/router';
import {Login} from '../login/login';
import {UserService} from '../../Services/userService'; // a service to handle auth

@Directive({
  selector: 'router-outlet'
})
export class AuthRouterOutlet extends RouterOutlet {
  publicRoutes: any;
  private parentRouter: Router;

  constructor(private _userService:UserService, _elementRef: ElementRef, _loader: DynamicComponentLoader,
              _parentRouter: Router, @Attribute('name') nameAttr: string) {
    super(_elementRef, _loader, _parentRouter, nameAttr);

    this.parentRouter = _parentRouter;
    this.publicRoutes = {
      '/login': true,
      '/signup': true
    };
    // publicRoutes will be the routes auth is not needed for.
  }

  activate(instruction: ComponentInstruction) {
    var url = this.parentRouter.lastNavigationAttempt;
    if (!this.publicRoutes[url] && this._userService.getAuth()) {
      // todo: redirect to Login, may be there a better way?
      this.parentRouter.navigateByUrl('/login');
    }
    return super.activate(instruction);
    // we return super.activate(instruction) here so the router can activate the requested route and it's components.
  }
}

Esta implementación maneja cualquier nueva solicitud a una directiva y ejecuta la función activate donde estará su lógica de autenticación de rutas. El código anterior se llamaría algo como AuthRouterOutlet, y tendría que agregarlo a su app.ts a través de

directives: [ AuthRouterOutlet]

Respuesta #2

Con la nueva versión beta del enrutador, también puedes ver mi respuesta aquí sobre cómo usar la interfaz CanActivate:

https://stackoverflow.com/a/38369948/1944351

Usar el decorador como se menciona en otra respuesta también está bien.

Artículos relacionados