Vengo del mundo Asp.Net MVC donde los usuarios que intentan acceder a una página que no están autorizados son redirigidos automáticamente a la página de inicio de sesión.
Estoy tratando de reproducir este comportamiento en Angular. Me encontré con el decorador @CanActivate, pero el componente no se representa en absoluto, no hay redirección.
Mi pregunta es la siguiente:
- ¿Angular proporciona una forma de lograr este comportamiento?
- ¿Si es así, cómo? ¿Es una buena práctica?
- Si no es así, ¿cuál sería la mejor práctica para manejar la autorización del usuario en Angular?
login
typescript
angular
angular2-routing
Amaury
fuente
fuente
Respuestas:
Actualización: publiqué un proyecto esqueleto completo de Angular 2 con integración OAuth2 en Github que muestra la directiva mencionada a continuación en acción.
Una forma de hacerlo sería mediante el uso de un
directive
. A diferencia de Angular 2components
, que son básicamente etiquetas HTML nuevas (con código asociado) que inserta en su página, una directiva atributiva es un atributo que coloca en una etiqueta que hace que ocurra algún comportamiento. Documentos aquí .La presencia de su atributo personalizado hace que sucedan cosas en el componente (o elemento HTML) en el que colocó la directiva. Considere esta directiva que uso para mi aplicación Angular2 / OAuth2 actual:
Esto hace uso de un servicio de autenticación que escribí para determinar si el usuario ya inició sesión o no y también se suscribe al evento de autenticación para que pueda expulsar a un usuario si cierra sesión o se agota el tiempo de espera.
Podrías hacer lo mismo. Crearía una directiva como la mía que verifica la presencia de una cookie necesaria u otra información de estado que indique que el usuario está autenticado. Si no tienen esas banderas que está buscando, redirija al usuario a su página pública principal (como yo) o su servidor OAuth2 (o lo que sea). Pondría ese atributo de directiva en cualquier componente que necesite protección. En este caso, podría llamarse
protected
como en la directiva que pegué anteriormente.Luego, querrá navegar / redirigir al usuario a una vista de inicio de sesión dentro de su aplicación y manejar la autenticación allí. Tendría que cambiar la ruta actual por la que deseaba hacer. Entonces, en ese caso, usaría la inyección de dependencia para obtener un objeto Router en la
constructor()
función de su directiva y luego usaría elnavigate()
método para enviar al usuario a su página de inicio de sesión (como en mi ejemplo anterior).Esto supone que tiene una serie de rutas en algún lugar controlando una
<router-outlet>
etiqueta que se parece a esto, tal vez:Si, en cambio, necesitara redirigir al usuario a una URL externa , como su servidor OAuth2, entonces su directiva haría algo como lo siguiente:
fuente
Aquí hay un ejemplo actualizado usando Angular 4 (también compatible con Angular 5-8)
Rutas con ruta local protegida por AuthGuard
AuthGuard redirige a la página de inicio de sesión si el usuario no ha iniciado sesión
Actualizado para pasar la URL original en los parámetros de consulta a la página de inicio de sesión
Para ver el ejemplo completo y la demostración funcional, puede consultar esta publicación
fuente
currentUser
en ellocalStorage
? p.ej.localStorage.setItem('currentUser', 'dddddd')
?Uso con el enrutador final
Con la introducción del nuevo enrutador se hizo más fácil proteger las rutas. Debe definir un guardia, que actúa como un servicio, y agregarlo a la ruta.
Ahora pase el
LoggedInGuard
a la ruta y también agréguelo a laproviders
matriz del módulo.La declaración del módulo:
Publicación de blog detallada sobre cómo funciona con la versión final: https://medium.com/@blacksonic86/angular-2-authentication-revisited-611bf7373bf9
Uso con el enrutador obsoleto
Una solución más sólida es extender el
RouterOutlet
y al activar una ruta, verifique si el usuario está conectado. De esta manera, no tiene que copiar y pegar su directiva en cada componente. Además, la redirección basada en un subcomponente puede ser engañosa.los
UserService
representa el lugar donde reside la lógica de negocio si el usuario está conectado o no. Puede agregarlo fácilmente con DI en el constructor.Cuando el usuario navega a una nueva URL en su sitio web, se llama al método de activación con la instrucción actual. Desde allí, puede tomar la URL y decidir si está permitida o no. Si no, simplemente redirija a la página de inicio de sesión.
Una última cosa que queda para que funcione, es pasarlo a nuestro componente principal en lugar del integrado.
Esta solución no se puede utilizar con el
@CanActive
decorador de ciclo de vida, porque si la función que se le pasa se resuelve como falso, el método de activación delRouterOutlet
no se llamará al .También escribí una publicación de blog detallada al respecto: https://medium.com/@blacksonic86/authentication-in-angular-2-958052c64492
fuente
Failed to lint <classname>.router-outlet.ts[15,28]. In the constructor of class "LoggedInRouterOutlet", the parameter "nameAttr" uses the @Attribute decorator, which is considered as a bad practice. Please, consider construction of type "@Input() nameAttr: string".
No pude averiguar qué cambiar en el constructor ("_parentRounter") para deshacerme de este mensaje. ¿Alguna idea?_parentRouter: Router, @Input() nameAttr: string,
ay tslint ya no genera el error. También reemplazó la importación de "Atributo" a "Entrada" desde el núcleo angular. Espero que esto ayude.¡Por favor, no anule la salida del enrutador! Es una pesadilla con la última versión del enrutador (3.0 beta).
En su lugar, utilice las interfaces CanActivate y CanDeactivate y configure la clase como canActivate / canDeactivate en su definición de ruta.
Como eso:
Clase:
Véase también: https://angular.io/docs/ts/latest/guide/router.html#!#can-activate-guard
fuente
Siguiendo las impresionantes respuestas anteriores, también me gustaría
CanActivateChild
: proteger las rutas de los niños. Se puede usar para agregarguard
a los niños rutas útiles para casos como ACLDice así
Esto está tomado de https://angular.io/docs/ts/latest/guide/router.html#!#can-activate-guard
fuente
Consulte este código, archivo auth.ts
fuente
1. Create a guard as seen below. 2. Install ngx-cookie-service to get cookies returned by external SSO. 3. Create ssoPath in environment.ts (SSO Login redirection). 4. Get the state.url and use encodeURIComponent.
fuente