angularjs - pantalla - Acceda al alcance o servicio en el enrutador ui enIntro para verificar el acceso(autenticación)
pagina de login en ionic (6)
Ok, tengo un estado para la url "/ securepage" que necesito verificar cada vez que un usuario intente acceder a ella. Así que leí que hay una función onEnter que puedo usar. Pero parece que no puedo apoderarme del alcance ni de un servicio desde allí. ¿Qué estoy haciendo mal?
.state(''securepage'', {
url: "/securepage",
template: securepage.html,
onEnter: function(){
// if (!$scope.main.isAuthenticated) $state.go("/login");
// if (!myLoginService.currentUser()) $state.go("/login");
Las opciones actuales que veo son usar resolver y / o verificar la autenticación en el controlador. ¿Pero no sería mejor colocar un cheque de autenticación en onEnter?
Estoy usando angularjs 1.3 con ui.router 0.2.10
Estoy seguro de que muchas cosas han cambiado desde que se hizo esta pregunta, pero como tuve que resolverlo por mí mismo y mi búsqueda me condujo hasta aquí ...
En cuanto a la verificación de la autenticación, podrías hacerlo así.
.state(''securepage'', {
url: "/securepage",
template: securepage.html,
onEnter: function($scope,$state,myLoginService){ //THIS IS THE CHANGE
if (!$scope.main.isAuthenticated) $state.go("/login");
if (!myLoginService.currentUser()) $state.go("/login");
Puede poner prácticamente proveedor / servicio / fábrica en la función onEnter para obtener acceso a él, y esto funciona desde dentro del .config de la aplicación.
Habiendo dicho eso, ellos (los fabricantes de enrutadores ui) sugieren usar una función de regla personalizada que se maneje dentro. $ On (''$ stateChangeStart'', function (e, to) https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-create-rules-to-prevent-access-to-a-state No sé por qué hacen esto en lugar de onEnter, tal vez alguien pueda ampliarlo.
Me encontré con un problema similar hoy. Pasé un día entero y, finalmente, se me ocurrió una solución viable distinta a las ya sugeridas aquí.
Mi objetivo principal es encontrar una manera fácil y efectiva de proteger selectivamente ciertas páginas web específicas. La comprobación de seguridad debe realizarse antes de que se cargue o se llame al HTML o a cualquiera de los controladores relevantes. Si la comprobación falla, la página puede reenviarse a otro lugar sin ningún efecto secundario de los otros controladores.
Probé los otros enfoques sugeridos. Cada uno tiene su propio conjunto de problemas:
Usando OnEnter:
- No hay manera de impedir que el ui-router continúe con la transición de estado mientras se realiza una llamada asíncrona para realizar la comprobación de seguridad.
Utilizando $ rootScope. $ On (''$ stateChangeStart''):
- La administración de los estados que requieren verificación de seguridad se separará de las definiciones de $ stateProvider.state (). Idealmente, preferiría ver todo sobre la definición de un estado definido en un solo lugar. Aunque esto no es un showstopper, no es ideal.
- Un problema mucho mayor es que no se llama al evento $ stateChangeStart para la carga inicial de una página. Este es un showstopper.
Mi solución es usar una función de resolución para definir una promesa que hará que los controladores de la vista esperen a que se complete el aplazamiento antes de que se llame. Esto funciona perfectamente para evitar que el controlador se inicie de forma asíncrona.
Aquí hay un resumen del código que utilicé:
.config([''$stateProvider'', function ($stateProvider) {
// Handler for Restricting Access to a page using the state.resolve call
var accessRestrictionHandler = function($q, $rootScope, $state) {
var deferred = $q.defer();
// make sure user is logged in
asyncCheckForLogin(function(status) {
if (status != "Logged In") {
// You may save target page URL in cookie for use after login successful later
// To get the relative target URL, it is equal to ("#" + this.url).
// The "this" here is the current scope for the parent state structure of the resolve call.
$state.go("loginPage");
}
else // if logged in, continue to load the controllers. Controllers should not start till resolve() is called.
deferred.resolve();
}.bind(this));
return deferred.promise;
};
$stateProvider
.state(''userProfile'', {
url: ''/userProfile'',
views: {
''main'': {
templateUrl: ''userProfile.html'',
controller: ''userProfileCtrl''
}
},
// SIMPLY add the line below to all states that you want to secure
resolve: { loginRequired : accessRestrictionHandler }
})
.state(.... some other state)
.state(.... some other state);
}]);
Espero que esto ayude a algunos de ustedes por ahí.
Otro enfoque sería que un servicio / controlador escuche el evento "$ stateChangeStart". Allí, puede verificar si el estado llamado necesita autenticación y redireccionar la solicitud. Aquí hay un fragmento de código:
$rootScope.$on(''$stateChangeStart'', function (event, nextState, currentState) {
if (!isAuthenticated(nextState)) {
console.debug(''Could not change route! Not authenticated!'');
$rootScope.$broadcast(''$stateChangeError'');
event.preventDefault();
$state.go(''login'');
}
});
isAuthenticated
podría retener la llamada a sus servicios, consultar nextState.data
para las propiedades relacionadas con la autenticación, etc.
Una respuesta tardía pero bueno prefiero escribirla de todos modos. Prefiero no tocar el $ rootScope siempre que sea posible. Aquí está el código en el que estoy trabajando actualmente, que resume otra solución para su pregunta:
state(''dash'', {
url:''/'',
views:{
"topNav":{
templateUrl:"user/dash/partials/top-nav.html",
controller:''logoutCtrl'',
},
"sideNav":{
templateUrl:"user/dash/partials/side-nav.html"
},
"body":{
templateUrl:"user/dash/partials/body.html",
controller:''testCtrl''
}
},
onEnter: function(Auth, $state){
if(!AuthSvc.isAuthenticated){
$state.go(''login'');
}
}
})
Estoy usando JWT para almacenar los tokens en el almacenamiento local utilizando ngStorage, que proporciona un servicio de $ localStorage que inyecto en la fábrica de Auth que inyecté enEnter
probablemente te refieres
.state(''securepage'', {
url: "/securepage",
template: securepage.html,
//this is how you actually inject things to onEnter property
onEnter: [''$state'',''myLoginService'',function($state,myLoginService){
if (!$scope.main.isAuthenticated) $state.go("/login");
if (!myLoginService.currentUser()) $state.go("/login");`}]
....