AngularJs SPA 注销
AngularJs SPA logout
我在这里发布了更复杂的问题 AngularJs logout action。但我还有另一个方面要看,我认为这应该是分开的问题。
我有带身份验证的 Angualr SPA。使用不记名 JWT 令牌实现的身份验证。我用ng-route
来表达不同的看法。让我们想象一下,一个视图(使用 /protected
路由、protecetedController
和 protectedDataService
)包含受保护的资源,而另一个视图(使用 /unprotected
路由、unprotecetedController
和unprotectedDataService
) 包含不受保护的资源。控制器示例代码:
(function () {
'use strict';
angular
.module('protectedCtrl',[])
.controller('protectedController', ['$location','protectedDataService', function ($location, protectedDataService) {
var vm = this;
vm.title = 'protectedController';
protectedDataService.getData().then(function (res) {
vm.values = res.data;
}, function (err) {
console.log(err);
});
}]);
})();
未受保护的控制器:
(function () {
'use strict';
angular
.module('unprotectedCtrl',[])
.controller('unprotectedController', ['$location','unprotectedDataService', function ($location, unprotectedDataService) {
var vm = this;
vm.title = 'unprotectedController';
unprotectedDataService.getData().then(function (res) {
vm.values = res.data;
}, function (err) {
console.log(err);
});
}]);
})();
如果未登录的用户转到受保护的资源(/protected
路径),他将被重定向到登录页面。但是让我们想象一下,登录用户按下注销按钮(现在我只是从浏览器本地策略中删除我的令牌信息并重新加载页面)。如果用户在 /protected
页面上,他应该被重定向到登录页面。如果他在 /unprotected
页面上,则不会发生任何事情。我该如何实施?如何确定哪个页面在 ng-view
中处于活动状态(是否需要授权)并决定重定向?
您可以使用 $routeChangeStart
事件来捕捉路由的变化和辅助函数来决定是否重定向到登录页面。
在 angular 应用程序的 run
块中,为不需要身份验证的路线定义一个变量,并定义一个函数来检查用户前往的路线是否在此列表中。
angular
.module('awesomeApp')
.run(function (/* inject dependencies */) {
// other code
// Define a list of routes that follow a specific rule. This example
// can be extended to provide access based on user permissions by
// defining other variables that will list routes that require the
// user to have specific permissions to access those routes.
var routesThatDoNotRequireAuthentication = ['/unprotected'];
// Check if current location is contained in the list of given routes.
// Note: the check here can be made using different criteria. For
// this example I check whether the route contains one of the
// available routes, but you can check for starting position, or other criteria.
function rootIsPresent ( route, availableRoutes ) {
var routeFound = false;
for ( var i = 0, l = availableRoutes.length; i < l; i++ ) {
routeFound = routeFound || route.indexOf(availableRoutes[i]) > -1;
}
return routeFound;
}
// And now, when the $routeChangeStart event is fired, check whether
// its safe to let the user change the route.
$rootScope.$on('$routeChangeStart', function () {
// Get the authentication status of a user
var isAuthenticated = authenticationService.isAuthenticated();
var newRoute = $location.url();
// If the route requires authentication and the user is not
// authenticated, then redirect to login page.
if ( !rootIsPresent(newRoute, routesThatDoNotRequireAuthentication) && !isAuthenticated ) {
$location.path('/login');
}
});
});
更新
似乎我误解了这个问题并认为你所有的路线都以 /protected
或 /unprotected
为前缀(如果你考虑一下,这真的不是那么聪明大多数情况下都会这样做)。
在这种情况下,您可以在$routeProvider
中定义路由时额外设置属性:
$routeProvider
.when('/awesomePath', {
templateUrl: 'awesome-template.html',
controller: 'AwesomeController',
controllerAs: 'vm',
requireAuth: true // add the property that defines a route as protected or unprotected
})
现在,在您的 $routeChangeStart
处理程序函数中,您检查用户将要前往的路由是否受到保护:
$rootScope.$on('$routeChangeStart', function () {
// Get the authentication status of a user
var isAuthenticated = authenticationService.isAuthenticated();
var newRoute = $location.url();
// In a controller, $route object has a 'current' property that
// holds route defined route properties, but here the 'current'
// property is null, so we need to get the $route object we
// need by using the $location.url()
if ( $route.routes[$location.url()].requireAuth && !isAuthenticated ) {
$location.path('/login');
}
});
因此您无需在任何地方对路线进行硬编码。
我在这里发布了更复杂的问题 AngularJs logout action。但我还有另一个方面要看,我认为这应该是分开的问题。
我有带身份验证的 Angualr SPA。使用不记名 JWT 令牌实现的身份验证。我用ng-route
来表达不同的看法。让我们想象一下,一个视图(使用 /protected
路由、protecetedController
和 protectedDataService
)包含受保护的资源,而另一个视图(使用 /unprotected
路由、unprotecetedController
和unprotectedDataService
) 包含不受保护的资源。控制器示例代码:
(function () {
'use strict';
angular
.module('protectedCtrl',[])
.controller('protectedController', ['$location','protectedDataService', function ($location, protectedDataService) {
var vm = this;
vm.title = 'protectedController';
protectedDataService.getData().then(function (res) {
vm.values = res.data;
}, function (err) {
console.log(err);
});
}]);
})();
未受保护的控制器:
(function () {
'use strict';
angular
.module('unprotectedCtrl',[])
.controller('unprotectedController', ['$location','unprotectedDataService', function ($location, unprotectedDataService) {
var vm = this;
vm.title = 'unprotectedController';
unprotectedDataService.getData().then(function (res) {
vm.values = res.data;
}, function (err) {
console.log(err);
});
}]);
})();
如果未登录的用户转到受保护的资源(/protected
路径),他将被重定向到登录页面。但是让我们想象一下,登录用户按下注销按钮(现在我只是从浏览器本地策略中删除我的令牌信息并重新加载页面)。如果用户在 /protected
页面上,他应该被重定向到登录页面。如果他在 /unprotected
页面上,则不会发生任何事情。我该如何实施?如何确定哪个页面在 ng-view
中处于活动状态(是否需要授权)并决定重定向?
您可以使用 $routeChangeStart
事件来捕捉路由的变化和辅助函数来决定是否重定向到登录页面。
在 angular 应用程序的 run
块中,为不需要身份验证的路线定义一个变量,并定义一个函数来检查用户前往的路线是否在此列表中。
angular
.module('awesomeApp')
.run(function (/* inject dependencies */) {
// other code
// Define a list of routes that follow a specific rule. This example
// can be extended to provide access based on user permissions by
// defining other variables that will list routes that require the
// user to have specific permissions to access those routes.
var routesThatDoNotRequireAuthentication = ['/unprotected'];
// Check if current location is contained in the list of given routes.
// Note: the check here can be made using different criteria. For
// this example I check whether the route contains one of the
// available routes, but you can check for starting position, or other criteria.
function rootIsPresent ( route, availableRoutes ) {
var routeFound = false;
for ( var i = 0, l = availableRoutes.length; i < l; i++ ) {
routeFound = routeFound || route.indexOf(availableRoutes[i]) > -1;
}
return routeFound;
}
// And now, when the $routeChangeStart event is fired, check whether
// its safe to let the user change the route.
$rootScope.$on('$routeChangeStart', function () {
// Get the authentication status of a user
var isAuthenticated = authenticationService.isAuthenticated();
var newRoute = $location.url();
// If the route requires authentication and the user is not
// authenticated, then redirect to login page.
if ( !rootIsPresent(newRoute, routesThatDoNotRequireAuthentication) && !isAuthenticated ) {
$location.path('/login');
}
});
});
更新
似乎我误解了这个问题并认为你所有的路线都以 /protected
或 /unprotected
为前缀(如果你考虑一下,这真的不是那么聪明大多数情况下都会这样做)。
在这种情况下,您可以在$routeProvider
中定义路由时额外设置属性:
$routeProvider
.when('/awesomePath', {
templateUrl: 'awesome-template.html',
controller: 'AwesomeController',
controllerAs: 'vm',
requireAuth: true // add the property that defines a route as protected or unprotected
})
现在,在您的 $routeChangeStart
处理程序函数中,您检查用户将要前往的路由是否受到保护:
$rootScope.$on('$routeChangeStart', function () {
// Get the authentication status of a user
var isAuthenticated = authenticationService.isAuthenticated();
var newRoute = $location.url();
// In a controller, $route object has a 'current' property that
// holds route defined route properties, but here the 'current'
// property is null, so we need to get the $route object we
// need by using the $location.url()
if ( $route.routes[$location.url()].requireAuth && !isAuthenticated ) {
$location.path('/login');
}
});
因此您无需在任何地方对路线进行硬编码。