Angular:处理重新加载页面和用户身份验证
Posted
技术标签:
【中文标题】Angular:处理重新加载页面和用户身份验证【英文标题】:Angular: Dealing with reload page and User Authentication 【发布时间】:2016-08-13 15:54:58 【问题描述】:我一直在使用一个记录用户的应用程序。一旦用户登录,用户的信息就会存储在服务中,并且 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-router 我这样做: 有角度的 .module('我的模块') .run(runFn);
runFn.$inject = ['$state', '$rootScope', 'AuthService', '$cookieStore'];
function runFn($state, $rootScope, AuthService, $cookieStore)
$rootScope.$on('$stateChangeSuccess', stateTransitioned);
function stateTransitioned(e, toState, toParams, fromState, fromParams)
var pageRealoaded = fromState.name? false : true;
if(AuthService.getUser())
//DEALING WITH STATES TRANSITIONS
else
if($cookieStore.get('auth_token') && pageRealoaded)
//ENSURE THAT THE USER IS LOGGED WHEN THE STATE IS CHANGED
AuthService.reloadUser.then(function()
$state.go(toState.name);
)
.catch($state.go.bind(null,'login'));
//I DON'T KNOW HOW AVOID THAT THE STATE IS LOADED UNTIL THE USER
//HAVE BEEN LOGGED
else
$state.go('login');
当页面重新加载时,使用存储的令牌,我尝试等待该用户已登录,然后,如果成功,则重定向到状态toState.name
,如果错误,则重定向到登录。
我的问题:
1.如何避免在用户登录之前加载状态?
2。我处理这种情况的架构是否正确?对更好结构的建议?
【问题讨论】:
试试这个答案:***.com/questions/22537311/… 它详细介绍了如何处理状态、登录、如何存储身份验证状态等。 【参考方案1】:我建议您使用 ui-router 的解析功能来确保用户在进入状态之前始终经过身份验证。
在此处查看 ui-router wiki: https://github.com/angular-ui/ui-router/wiki#resolve
这样的事情应该会阻止身份验证之前的状态输入。
.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>
)
我还将这支笔与一个工作示例放在一起: http://codepen.io/marcus-r/pen/eZKbYV?editors=1010
【讨论】:
我想避免对我的所有州重复此代码(我有超过 10 个州)。 查看代码笔。您可以使用secure
作为所有需要身份验证的页面的父状态。您将看到有两个页面secure.page1
和secure.page2
。两者都需要身份验证,但保护仅在 secure
上实施一次。
哦!我没看懂你的想法!!为此使用父状态,这是一个好主意!谢谢!【参考方案2】:
最后,对于我的第一个问题,我创建了以下示例,展示了我如何防止状态更改,直到用户成功登录。
http://codepen.io/gpincheiraa/pen/zqLYZz
在这个例子中,当我转到“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:处理重新加载页面和用户身份验证的主要内容,如果未能解决你的问题,请参考以下文章
如何在angular4的firebase电话身份验证中重新发送短信验证?