Ho un'app angolare che utilizza la logica di autorizzazione e l'ui-router per bloccare utenti non autorizzati per determinati stati/viste. Seguo l'approccio standard di ascolto per un evento stateChange, che attiva la mia logica di autorizzazione. Tutto funziona bene finché non viene ricaricata la pagina temuta.Come posticipare un evento StateChangeStart fino a dopo l'esecuzione di una risoluzione del router uu
Memorizzo i dati di sessione (incluso lo stato di autorizzazione) nella memoria locale in modo che sulla pagina si ricarichi Posso usare uno stato genitore in ui-router per risolvere prima/ottenere lo stato di autorizzazione dalla memoria locale prima di tentare di cambiare vista. Ecco la configurazione del mio oggetto di stato app
genitore:
$stateProvider.
state('app', {
url: '/app',
abstract: true,
controller: 'appCtrl',
data: {
authorizedRoles: [USER_ROLES.all]
},
templateUrl: 'partials/app.html',
resolve: {
//Try to restore from the previous session before loading any of the app child states
RestoredSession: ['SessionService',
function(SessionService){
return SessionService.restoreSession();
}]
}
})
...various app. child states
Ed ecco la mia onStateChange ascoltatore:
//listen for a ui.router $stateChangeStart event and test the new path to see if the currentUser
//is authorized to view that page
.run( ['$rootScope', 'AUTH_EVENTS', 'SessionService',
function ($rootScope, AUTH_EVENTS, SessionService) {
$rootScope.$on('$stateChangeStart', function (event, next) {
var authorizedRoles = next.data.authorizedRoles;
//If the requested page allows guest access, then continue to stateChange
if (authorizedRoles.indexOf('guest') !== -1 || authorizedRoles.indexOf('*') !== -1) return;
//If the requested page requires authorization, check login and auth privileges
if (!SessionService.isAuthorized(authorizedRoles)) {
event.preventDefault();
if (SessionService.existingSession()) {
// user is not allowed
$rootScope.$broadcast(AUTH_EVENTS.notAuthorized);
console.log("User attempted to access page for which he is not authorized");
} else {
// user is not logged in
$rootScope.$broadcast(AUTH_EVENTS.notLoggedIn);
console.log("User attempted to access page when he is not logged in");
}
}
});
}]);
Il mio problema è che l'evento stateChangeStart
sta provocando prima delle app resolve
tale che le fermate ascoltatore il cambio di stato (tramite lo event.preventDefault
), e quindi la mia risoluzione carica i dati di sessione memorizzati, che spesso stabiliscono che l'utente è stato autorizzato per tutto il tempo. Se potessi richiedere l'esecuzione della risoluzione prima dell'attivazione dell'evento, sarei d'oro.
Qualche idea là fuori ???
BTW, qui è una domanda simile in modo che è rimasta senza risposta: Defer Angular UI Router $stateChangeStart until server authorization response receieved
Questa risposta può aiutare: http://stackoverflow.com/a/21098923/1873485 – TheSharpieOne