Confundindo $ locationChangeSuccess e $ stateChangeStart

Eu estou tentando fazer alguma autenticação com o AngularUI Router. $urlRouter.sync() parece exatamente o que eu preciso. No entanto, isso só está disponível quando eu interceptar $locationChangeSuccess . Mas quando eu faço isso, $state.current.name está vazio, enquanto eu quero que seja o estado atual.

Aqui está o meu código até agora:

 $rootScope.$on('$locationChangeSuccess', function(event, next, nextParams) { event.preventDefault(); if ($state.current.name === 'login') { return userService.isAuthenticated().then(function(response) { var authenticated; authenticated = response.authenticated; return alert(authenticated); }); } }); 

Quaisquer indicações sobre o que estou fazendo errado?

Eu sugiro ir mais “maneira de UI-Router “. Nós devemos usar $rootScope.$on('$stateChangeStart' evento $rootScope.$on('$stateChangeStart' onde $state.current seria apropriadamente fornecido. Aqui está um exemplo funcional

Vamos observar uma solução simples (mas não ingênua) , que poderia ser estendida para qualquer grau posterior. Além disso, se você quiser essa abordagem, aqui está uma implementação muito mais abrangente: autenticação de login do roteador ui angular

Em primeiro lugar, vamos ter nosso serviço de usuário definido assim:

 .factory('userService', function ($timeout, $q) { var user = undefined; return { // async way how to load user from Server API getAuthObject: function () { var deferred = $q.defer(); // later we can use this quick way - // - once user is already loaded if (user) { return $q.when(user); } // server fake call, in action would be $http $timeout(function () { // server returned UN authenticated user user = {isAuthenticated: false }; // here resolved after 500ms deferred.resolve(user) }, 500) return deferred.promise; }, // sync, quick way how to check IS authenticated... isAuthenticated: function () { return user !== undefined && user.isAuthenticated; } }; }) 

Então, usamos async (aqui $timeout ) para carregar user object de user um servidor. Em nosso exemplo, ele terá uma propriedade {isAuthenticated: false } , que será usada para verificar se está autenticada.

Há também o método sync isAuthenticated() que, até que o usuário seja carregado e permitido, sempre retorna false .

E esse seria nosso ouvinte do evento '$stateChangeStart' :

 .run(['$rootScope', '$state', 'userService', function ($rootScope, $state, userService) { $rootScope.$on('$stateChangeStart', function (event, toState, toParams , fromState, fromParams) { // if already authenticated... var isAuthenticated = userService.isAuthenticated(); // any public action is allowed var isPublicAction = angular.isObject(toState.data) && toState.data.isPublic === true; if (isPublicAction || isAuthenticated) { return; } // stop state change event.preventDefault(); // async load user userService .getAuthObject() .then(function (user) { var isAuthenticated = user.isAuthenticated === true; if (isAuthenticated) { // let's continue, use is allowed $state.go(toState, toParams) return; } // log on / sign in... $state.go("login"); }) ... 

O que estamos verificando primeiro é se o usuário já está carregado e autenticado ( var isAuthenticated = ... ) . Em seguida, vamos dar verde a qualquer método público. Isso é feito com a propriedade data {} da definição de object de estado (consulte Anexar dados personalizados a objects de estado )

E é isso. No caso de estados definidos como em um trecho abaixo, podemos experimentar:

  • o 'public' , 'home' é permitido a qualquer pessoa
  • o 'private' , 'private' irá redirect para o login se isAuthenticated === false
  • o 'login' neste exemplo fornece uma maneira rápida de ativar / desativar oAuthenticated

     // States $stateProvider // public .state('home', { url: "/home", templateUrl: 'tpl.html', data: { isPublic: true }, }) .state('public', { url: "/public", templateUrl: 'tpl.html', data: { isPublic: true }, }) // private .state('private', { url: "/private", templateUrl: 'tpl.html', }) .state('private2', { url: "/private2", templateUrl: 'tpl.html', }) // login .state('login', { url: "/login", templateUrl: 'tpl.html', data: { isPublic: true }, controller: 'loginCtrl', }) 

Verifique que tudo aqui

Alguns outros resources:

  • autenticação de login do roteador ui angular
  • Roteador de interface do usuário angular: estados nesteds para que o usuário faça logon e logout
  • outros data e autenticação do estado