Javascript 角度:处理重新加载页面和用户身份验证

Javascript 角度:处理重新加载页面和用户身份验证,javascript,angularjs,cookies,angular-ui-router,reload,Javascript,Angularjs,Cookies,Angular Ui Router,Reload,我一直在一个记录用户日志的应用程序中工作。用户登录后,用户的信息将存储在服务中,并使用auth令牌存储cookie。 像这样: angular .module('MyModule') .service('AuthService', service); service.$inject = ['$cookieStore', '$resource']; function service($cookieStore, $resource){ var self = this, use

我一直在一个记录用户日志的应用程序中工作。用户登录后,用户的信息将存储在服务中,并使用auth令牌存储cookie。 像这样:

angular
 .module('MyModule')
 .service('AuthService', service);

service.$inject = ['$cookieStore', '$resource'];

function service($cookieStore, $resource){
  var self = this,
      user = null; 

  self.loginResource = $resource('my_path_to_login_resource');

  self.login = login;
  self.getUser = getUser;
  self.reloadUser = reloadUser; 


  function login(_userCredentials){
    var userResource = new self.loginResource(_userCredentials);
    return userResource.$save()
           .then(setUser);
  }

  function setUser(_userResponse){
    user = _userResponse.toJSON();
  }

  function getUser(){
    return user;
  }

  function reloadUser(_token){
    return self.loginResource()
            .get(_token)
            .then(setUser);
  }

}
当我需要处理应用程序的路由时,使用ui路由器,我可以执行以下操作: 有棱角的 .module('MyModule') .run(runFn)

当使用存储的令牌重新加载页面时,我尝试等待该用户已登录,如果成功,则重定向到state
toState.name
,如果出错,则重定向到login。 我的问题是:

1。如何避免在用户登录之前加载状态?


2。我处理这个案子的架构正确吗?关于更好结构的建议?

我建议您使用ui路由器的解析功能,以确保用户在进入状态之前始终经过身份验证

请参见此处的ui路由器wiki:

类似的内容应该可以防止在身份验证之前进入状态

.state('secure', {
    resolve: {
        user: function(AuthService, $state) {
            // State will only be entered if this resolves.
            return AuthService.resolveUser()
                .catch(function(error) {
                    $state.go('login');
                })
       }
    },
    template: '<div>Secret Page</div>
})
.state('secure'{
决心:{
用户:函数(AuthService,$state){
//只有在解决此问题时,才会输入状态。
返回AuthService.resolveUser()
.catch(函数(错误){
$state.go('login');
})
}
},
模板:'秘密页
})
我还将这支笔与一个工作示例组合在一起:

最后,对于我的第一个问题,我创建了以下示例,演示如何在用户成功登录之前防止状态更改

在本例中,当我转到“state3”时,我等待用户登录,然后重定向到该状态

angular
  .module('exampleApp', ['ui.router']);

angular
  .module('exampleApp')
  .config(configFn);

configFn.$inject = ['$stateProvider', '$urlRouterProvider'];

    function configFn($stateProvider, $urlRouterProvider){
      $urlRouterProvider.otherwise('state1');
        $stateProvider
         .state('state1', {
             url: '/state1',
           controller: ['$state', function($state){
               var  vm = this;
                 vm.current = $state.current.name;
                 vm.goTwo = function(){$state.go('state2');};
             }] ,
             controllerAs: 'one',
             template: '<h1>{{one.current}}</h1><button ng-click="one.goTwo()">Go to state 2</button>'
         })
        .state('state2', {
             url: '/state2',
           controller: ['$state', function($state){
               var  vm = this;
                 vm.current = $state.current.name;
                 vm.goThree = function(){$state.go('state3');};
             }] ,
             controllerAs: 'two',
             template: '<h1>{{two.current}}</h1><button ng-click="two.goThree()">Go to state 3</button>'
         })
        .state('state3', {
             url: '/state3',
           controller: ['$state', function($state){
               var  vm = this;
                 vm.current = $state.current.name;
             }] ,
             controllerAs: 'three',
             template: '<h1>{{three.current}}</h1>'
         })

    }

    angular
     .module('exampleApp')
     .run(runFn);
    runFn.$inject  = ['$rootScope','$timeout','$state'];
    function runFn($rootScope, $timeout, $state){

        var logged = false;

        $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
            console.log(toState.name);
            if(toState.name === 'state3' && !logged){

                //Fake like a user take a 1 second to login in server
                $timeout(function(){
                    logged = true;
                    console.log('login ok');
                    $state.go(toState.name);
                },1000)
                console.log('while the user not loggin, prevent the state change');
                event.preventDefault();
            }

        })


        }
angular
.module('exampleApp',['ui.router']);
有棱角的
.module('exampleApp')
.config(configFn);
configFn.$inject=['$stateProvider','$urlRouterProvider'];
函数configFn($stateProvider,$urlRouterProvider){
$urlRouterProvider。否则('state1');
$stateProvider
.州(“州1”{
url:“/state1”,
控制器:['$state',函数($state){
var vm=这个;
vm.current=$state.current.name;
vm.goTwo=function(){$state.go('state2');};
}] ,
controllerAs:'一',
模板:“{one.current}}转到状态2”
})
.州(“州2”{
url:“/state2”,
控制器:['$state',函数($state){
var vm=这个;
vm.current=$state.current.name;
vm.goThree=function(){$state.go('state3');};
}] ,
controllerAs:'两个',
模板:“{two.current}}转到状态3”
})
.州(“州3”{
url:“/state3”,
控制器:['$state',函数($state){
var vm=这个;
vm.current=$state.current.name;
}] ,
controllerAs:'三',
模板:“{three.current}”
})
}
有棱角的
.module('exampleApp')
.run(runFn);
runFn.$inject=['$rootScope','$timeout','$state'];
函数runFn($rootScope、$timeout、$state){
var=false;
$rootScope.$on(“$stateChangeStart”,函数(事件、toState、toParams、fromState、fromParams){
console.log(toState.name);
如果(toState.name=='state3'&&!已记录){
//假装用户需要1秒登录服务器
$timeout(函数(){
记录=真;
log('login ok');
$state.go(toState.name);
},1000)
log('当用户不登录时,防止状态更改');
event.preventDefault();
}
})
}

试试这个答案:它详细介绍了如何处理状态、登录、如何存储身份验证状态等。我希望避免在我所有的状态中重复此代码(我有超过10个状态)。请查看代码笔。您可以使用
secure
作为需要身份验证的所有页面的父状态。您将看到有两个页面
secure.page1
secure.page2
。两者都需要身份验证,但保护只在
secure
上实现一次。哦!我不明白你的想法!!为此使用父状态是一个好主意!谢谢
angular
  .module('exampleApp', ['ui.router']);

angular
  .module('exampleApp')
  .config(configFn);

configFn.$inject = ['$stateProvider', '$urlRouterProvider'];

    function configFn($stateProvider, $urlRouterProvider){
      $urlRouterProvider.otherwise('state1');
        $stateProvider
         .state('state1', {
             url: '/state1',
           controller: ['$state', function($state){
               var  vm = this;
                 vm.current = $state.current.name;
                 vm.goTwo = function(){$state.go('state2');};
             }] ,
             controllerAs: 'one',
             template: '<h1>{{one.current}}</h1><button ng-click="one.goTwo()">Go to state 2</button>'
         })
        .state('state2', {
             url: '/state2',
           controller: ['$state', function($state){
               var  vm = this;
                 vm.current = $state.current.name;
                 vm.goThree = function(){$state.go('state3');};
             }] ,
             controllerAs: 'two',
             template: '<h1>{{two.current}}</h1><button ng-click="two.goThree()">Go to state 3</button>'
         })
        .state('state3', {
             url: '/state3',
           controller: ['$state', function($state){
               var  vm = this;
                 vm.current = $state.current.name;
             }] ,
             controllerAs: 'three',
             template: '<h1>{{three.current}}</h1>'
         })

    }

    angular
     .module('exampleApp')
     .run(runFn);
    runFn.$inject  = ['$rootScope','$timeout','$state'];
    function runFn($rootScope, $timeout, $state){

        var logged = false;

        $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
            console.log(toState.name);
            if(toState.name === 'state3' && !logged){

                //Fake like a user take a 1 second to login in server
                $timeout(function(){
                    logged = true;
                    console.log('login ok');
                    $state.go(toState.name);
                },1000)
                console.log('while the user not loggin, prevent the state change');
                event.preventDefault();
            }

        })


        }