Soy nuevo en AngularJS, y estoy un poco confundido acerca de cómo puedo usar angular- "ui-router" en el siguiente escenario:
Estoy creando una aplicación web que consta de dos secciones. La primera sección es la página de inicio con sus vistas de inicio de sesión y registro, y la segunda sección es el panel de control (después de un inicio de sesión exitoso).
He creado una index.html
sección para la página de inicio con su aplicación angular y ui-router
configuración para manejar /login
y /signup
vistas, y hay otro archivo dashboard.html
para la sección del tablero con su aplicación y ui-router
configuración para manejar muchas vistas secundarias.
Ahora terminé la sección del tablero y no sé cómo combinar las dos secciones con sus diferentes aplicaciones angulares. ¿Cómo podría decirle a la aplicación de inicio que redirija a la aplicación de tablero?
fuente
Respuestas:
Estoy en el proceso de hacer una demostración más agradable y de limpiar algunos de estos servicios en un módulo utilizable, pero esto es lo que se me ocurrió. Este es un proceso complejo para evitar algunas advertencias, así que aguarde allí. Tendrás que dividir esto en varias partes.
Echa un vistazo a este golpe .
Primero, necesita un servicio para almacenar la identidad del usuario. Yo llamo a esto
principal
. Se puede verificar para ver si el usuario ha iniciado sesión y, si lo solicita, puede resolver un objeto que representa la información esencial sobre la identidad del usuario. Esto puede ser lo que necesite, pero lo esencial sería un nombre para mostrar, un nombre de usuario, posiblemente un correo electrónico y los roles a los que pertenece un usuario (si esto se aplica a su aplicación). El director también tiene métodos para hacer verificaciones de roles.En segundo lugar, necesita un servicio que verifique el estado al que quiere ir el usuario, se asegure de que haya iniciado sesión (si es necesario; no es necesario para iniciar sesión, restablecer la contraseña, etc.) y luego realice una verificación de roles (si su aplicación necesita esto). Si no están autenticados, envíelos a la página de inicio de sesión. Si están autenticados, pero fallan una verificación de roles, envíelos a una página de acceso denegado. Yo llamo a este servicio
authorization
.Ahora todo lo que necesitas hacer es escuchar en
ui-router
's$stateChangeStart
. Esto le brinda la oportunidad de examinar el estado actual, el estado al que desean ir e insertar su verificación de autorización. Si falla, puede cancelar la transición de ruta o cambiar a una ruta diferente.La parte difícil de rastrear la identidad de un usuario es buscarlo si ya se ha autenticado (por ejemplo, está visitando la página después de una sesión anterior y ha guardado un token de autenticación en una cookie, o tal vez ha actualizado una página, o cayó en una URL desde un enlace). Debido a la forma en que
ui-router
funciona, debe resolver su identidad una vez, antes de verificar su autenticación. Puede hacerlo utilizando laresolve
opción en la configuración de su estado. Tengo un estado principal para el sitio del que todos los estados heredan, lo que obliga al director a resolverse antes de que ocurra cualquier otra cosa.Hay otro problema aquí ...
resolve
solo se llama una vez. Una vez que su promesa de búsqueda de identidad se complete, no volverá a ejecutar el delegado de resolución. Por lo tanto, tenemos que hacer sus comprobaciones de autenticación en dos lugares: una vez de acuerdo con la resolución de su promesa de identidadresolve
, que cubre la primera vez que se carga su aplicación, y una vez$stateChangeStart
si la resolución se ha realizado, que cubre cualquier momento que navegue por los estados.Bien, ¿qué hemos hecho hasta ahora?
¿A dónde vamos desde aquí? Bueno, se puede organizar sus estados en regiones que requieren inicio de sesión. Puede requerir que los usuarios autenticados / autorizados mediante la adición
data
deroles
estos estados (o uno de los padres de ellos, si desea utilizar la herencia). Aquí, restringimos un recurso a los administradores:Ahora puede controlar estado por estado a qué usuarios pueden acceder una ruta. ¿Alguna otra inquietud? ¿Tal vez variar solo una parte de una vista en función de si están o no conectados? No hay problema. Use
principal.isAuthenticated()
o inclusoprincipal.isInRole()
con cualquiera de las numerosas formas en que puede mostrar condicionalmente una plantilla o un elemento.Primero, inyecte
principal
en un controlador o lo que sea, y adhiéralo al alcance para que pueda usarlo fácilmente desde su punto de vista:Mostrar u ocultar un elemento:
Etc., etc., etc. De todos modos, en su aplicación de ejemplo, tendría un estado para la página de inicio que permitiría la visita de usuarios no autenticados. Podrían tener enlaces a los estados de inicio o inicio de sesión, o tener esos formularios integrados en esa página. Lo que te venga bien.
Todas las páginas del panel podrían heredarse de un estado que requiere que los usuarios inicien sesión y, digamos, sean
User
miembros del rol. Todas las cosas de autorización que hemos discutido fluirían desde allí.fuente
$location.path
lugar de$state.go
.$scope.user
suthen
función. Todavía puede hacer referenciauser
en sus puntos de vista; cuando se resuelva, la vista se actualizará.$q.when(angular.noop).then(function(){$state.go('myState')
, todo funciona como se esperaba. Si llamo$state.go
mientras no se completa otra transición de estado, entonces no funcionará (creo que esa es la razón por la que no funcionará).Las soluciones publicadas hasta ahora son innecesariamente complicadas, en mi opinión. Hay una manera más simple. La documentación de
ui-router
dice escuchar$locationChangeSuccess
y usar$urlRouter.sync()
para verificar una transición de estado, detenerla o reanudarla. Pero incluso eso en realidad no funciona.Sin embargo, aquí hay dos alternativas simples. Elegir uno:
Solución 1: escuchando
$locationChangeSuccess
Puede escuchar
$locationChangeSuccess
y puede realizar algo de lógica, incluso lógica asincrónica allí. De acuerdo con esa lógica, puede dejar que la función regrese indefinida, lo que hará que la transición de estado continúe de manera normal, o puede hacerlo$state.go('logInPage')
, si el usuario necesita ser autenticado. Aquí hay un ejemplo:Tenga en cuenta que esto en realidad no impide que se cargue el estado de destino, pero sí redirige a la página de inicio de sesión si el usuario no está autorizado. Eso está bien, ya que la protección real está en el servidor, de todos modos.
Solución 2: usar estado
resolve
En esta solución, utiliza la
ui-router
función de resolución .Básicamente rechaza la promesa
resolve
si el usuario no está autenticado y luego lo redirige a la página de inicio de sesión.Así es como va:
A diferencia de la primera solución, esta solución realmente evita que se cargue el estado objetivo.
fuente
state A
. Hacen clic en un enlace para irprotected state B
pero desea redirigirloslogInPage
. Si no hay$timeout
,ui-router
simplemente detendrá todas las transiciones de estado, para que el usuario quede atrapadostate A
. Esto$timeout
permiteui-router
evitar primero la transición inicialprotected state B
porque la resolución fue rechazada y, una vez hecho, redirige alogInPage
.authenticate
llama realmente la función?authenticate
función @Imray se pasa como parámetro aui-router
. No tienes que llamarlo tú mismo.ui-router
lo llama$stateChangeStart
?La solución más fácil es usar
$stateChangeStart
yevent.preventDefault()
cancelar el cambio de estado cuando el usuario no está autenticado y redirigirlo al estado de autenticación que es la página de inicio de sesión.fuente
Creo que necesita un
service
que maneje el proceso de autenticación (y su almacenamiento).En este servicio necesitarás algunos métodos básicos:
isAuthenticated()
login()
logout()
Este servicio debe inyectarse en sus controladores de cada módulo:
service.isAuthenticated()
método). si no, redirigir a / iniciar sesiónservice.login()
métodoUn buen y robusto ejemplo de este comportamiento es la aplicación angular del proyecto y específicamente su módulo de seguridad que se basa en el impresionante Módulo Interceptor de Autenticación HTTP
Espero que esto ayude
fuente
Creé este módulo para ayudar a que este proceso sea sencillo
Puedes hacer cosas como:
O tambien
¡Es nuevo pero vale la pena echarle un vistazo!
https://github.com/Narzerus/angular-permission
fuente
Quería compartir otra solución trabajando con el enrutador ui 1.0.0.X
Como ya sabrás, stateChangeStart y stateChangeSuccess ahora están en desuso. https://github.com/angular-ui/ui-router/issues/2655
En su lugar, debe usar $ transitions http://angular-ui.github.io/ui-router/1.0.0-alpha.1/interfaces/transition.ihookregistry.html
Así es como lo logré:
Primero tengo y AuthService con algunas funciones útiles
Entonces tengo esta configuración:
Puedes ver que yo uso
para marcar el estado solo accesible si está autenticado.
luego, en el .run uso las transiciones para verificar el estado autenticado
Construyo este ejemplo usando algún código que se encuentra en la documentación de $ transitions. Soy bastante nuevo con el enrutador ui pero funciona.
Espero que pueda ayudar a cualquiera.
fuente
Así es como salimos del bucle de enrutamiento infinito y todavía lo usamos en
$state.go
lugar de$location.path
fuente
Tengo otra solución: esa solución funciona perfectamente cuando solo tiene contenido que desea mostrar cuando está conectado. Defina una regla en la que verifique si está conectado y no la ruta de las rutas de la lista blanca.
En mi ejemplo, pregunto si no he iniciado sesión y la ruta actual que quiero enrutar no es parte de `/ login ', porque mis rutas de la lista blanca son las siguientes
así que tengo acceso instantáneo a estas dos rutas y se comprobará cualquier otra ruta si está en línea.
Aquí está todo mi archivo de enrutamiento para el módulo de inicio de sesión
() => { /* code */ }
es la sintaxis de ES6, use en su lugarfunction() { /* code */ }
fuente
Use $ http Interceptor
Mediante el uso de un interceptor $ http, puede enviar encabezados a Back-end o al revés y hacer sus comprobaciones de esa manera.
Gran artículo sobre interceptores $ http
Ejemplo:
Ponga esto en su función .config o .run.
fuente
Primero necesitará un servicio que pueda inyectar en sus controladores que tenga alguna idea del estado de autenticación de la aplicación. Los detalles de autenticación persistentes con almacenamiento local son una forma decente de abordarlo.
A continuación, deberá verificar el estado de autenticación justo antes de los cambios de estado. Dado que su aplicación tiene algunas páginas que deben autenticarse y otras que no, cree una ruta principal que verifique la autenticación y haga que todas las demás páginas que requieren la misma sean secundarias de ese padre.
Finalmente, necesitará alguna forma de saber si su usuario actualmente conectado puede realizar ciertas operaciones. Esto se puede lograr agregando una función 'can' a su servicio de autenticación. Can toma dos parámetros: - acción - requerido - (es decir, 'manage_dashboards' o 'create_new_dashboard') - objeto - opcional - objeto en el que se opera. Por ejemplo, si tenía un objeto de tablero, es posible que desee verificar si dashboard.ownerId === loginInUser.id. (Por supuesto, la información transmitida por el cliente nunca debe ser confiable y siempre debe verificarla en el servidor antes de escribirla en su base de datos).
** DESCARGO DE RESPONSABILIDAD: El código anterior es un seudocódigo y viene sin garantías **
fuente