我有一个角度应用程序,通过基于令牌的身份验证系统与rails后端进行通信。
当我使用ngRoute时,我有一个拦截器,可以从cookie存储中获取令牌,并将其添加到每个向服务器发出请求的头文件中。
然后,如果令牌未经授权,它将侦听状态并重定向到登录。
如何使用ui-router执行此操作?它似乎没有相同的方式。
分享我提出的解决方案:
angular.module 'saAuthentication', []
.config ($stateProvider, $urlRouterProvider) ->
$stateProvider
.state 'login',
url: '/login',
templateUrl: 'app/authentication/sessions/login.html',
.run ($rootScope, $state, localStorageService) ->
$rootScope.$on "$stateChangeStart", (event, toState, toParams, fromState, fromParams) ->
if localStorageService.cookie.get('X-User-Token') == null
event.preventDefault()
$state.go('login', null, { notify: false }).then (state) ->
$rootScope.$broadcast('$stateChangeSuccess', state, null)
答案 0 :(得分:1)
您可以使用$stateChangeError
ui-router
documentation for state change events。$q
,$http
resolve
中的承诺接受或拒绝给定状态的身份验证,$stateChangeError
以转到其他州。在您的.config()
中以如此决定声明州:
app.config(['$stateProvider',function($stateProvider) {
$stateProvider.state('profile', {
url: '/profile',
template: '<h1>Hello authenticated user!</h1>',
resolve: {
authState: function($q, $timeout) {
var deferred = $q.defer();
//Simulate $http request with a $timeout
$timeout(function() {
deferred.reject("AUTH_REQUIRED");
}, 1000);
return deferred.promise;
}
}
});
}]);
并将$stateChangeError
观察者设置为.run()
,如下所示:
app.run(function ($rootScope, $state, $stateParams) {
$rootScope.$on("$stateChangeError", function(event, toState, toParams, fromState, fromParams, error) {
event.preventDefault();
if (error === "AUTH_REQUIRED") {
console.log("ERROR:", error, "URL:", toState.url, "PARAMS:", toParams);
//not authenticated, go to login instead of the route change
$state.go('login');
}
});
});
$timeout
来模拟身份验证错误。
'AUTH_REQUIRED'
。$stateChangeError
观察者捕获此错误,并做出相应的响应。$http
service发出身份验证请求,然后......
.success()
,.error()
中的承诺。以下是直接从$http
documentation发出请求的一般用法示例:
// Simple GET request example :
$http.get('/someUrl').
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
在.success()
中,您可以检查标题并相应地接受/拒绝承诺。您应该拒绝.error()
中的承诺。
希望有所帮助!
答案 1 :(得分:0)
不同之处在于使用ui-router收听$stateChangeStart
时收听事件。
$rootScope.$on('$stateChangeStart',
function (event, toState, toParams, fromState, fromParams) {
// redirect to login here if the token doesn't exist
})