在Laravel中,设置路由过滤器非常简单。我们使用beforeFilter([])
并指定控制器中的哪些函数可以在身份验证时访问,并且在特殊情况下也可以except
。
现在,我刚刚开始使用Angular的ui.router
,状态的概念肯定是前进的方向,但我在这里问一个noob问题。如何在我的州上设置路由过滤器。我绝对不想使用resolve
在各个路线上进行此操作。
这里有一些代码。这是我用于个人资料路线的内容。我使用resolve
来确保只有在经过身份验证时才能访问它。但问题是,当我登录时,我的登录和注册路由仍然可以访问。他们不应该。它应该只是重定向到家。
现在我可以将解决方案添加到我登录时不想访问的状态,但这是正确的方法吗?如果有很多怎么办?这将重复代码。是否有“ui.router”方式来做到这一点?
.state('profile', {
url: '/profile',
templateUrl: 'js/app/partials/profile.html',
controller: 'ProfileCtrl',
resolve: {
authenticated: function($q, $location, $auth) {
var deferred = $q.defer();
if (!$auth.isAuthenticated()) {
$location.path('/login');
} else {
deferred.resolve();
}
return deferred.promise;
}
}
})
答案 0 :(得分:2)
我认为一种方法是创建一个进行验证的服务,然后在运行块中,您可以在K.Toress提到的任何$stateChangeStart
事件上调用该服务。
例如,如果要指定需要进行身份验证的状态,可以使用状态定义配置中的数据选项来定义是否需要进行身份验证。因此,要定义需要身份验证的状态,您可以尝试类似......
$stateProvider
.state('foo', {
templateUrl: 'foo.html',
// etc...
data: {
requiresAuth: true
}
});
然后,您可以在$stateChangeStart
事件中检查此事件,该事件会传递toState
参数,您可以从该参数访问data
属性。
var app = angular.module('foo', ['ui.router'])
.factory('RouteValidator', ['$rootScope', '$auth', function($rootScope){
return {
init: init
};
function init(){
$rootScope.$on('$stateChangeStart', _onStateChangeStart);
}
function _onStateChangeStart(event, toState, toParams, fromState, fromParams){
// check the data property (if there is one) defined on your state
// object using the toState param
var toStateRequiresAuth = _requiresAuth(toState),
// if user is not authenticated and the state he is trying to access
// requires auth then redirect to login page
if(!$auth.isAuthenticated() && toStateRequiresAuth){
event.preventDefault();
$state.go('login');
return;
}
}
function _requiresAuth(toState){
if(angular.isUndefined(toState.data) || !toState.data.requiresAuth){
return false;
}
return toState.data.requiresAuth;
}
}])
.run(['RouteValidator', function(RouteValidator){
// inject service here and call init()
// this is so that you keep your run blocks clean
// and because it's easier to test the logic in a service than in a
// run block
RouteValidator.init();
}]);
修改强>
好的,我已经在plunker上做了一个非常基本的DEMO,希望能够展示这个概念。我也会在这里发布代码。帮助这有帮助。
<强> app.js 强>
var app = angular.module('plunker', ['ui.router']);
app.config(['$stateProvider', function($stateProvider){
$stateProvider
.state('public', {
url: "/public",
templateUrl: "public.html"
})
.state('login', {
url: "/login",
templateUrl: "login.html",
controller: function($scope) {
$scope.items = ["A", "List", "Of", "Items"];
}
})
.state('admin', {
url: "/admin",
templateUrl: "admin.html",
data: {
requiresAuth: true
},
controller: function($scope) {
$scope.items = ["A", "List", "Of", "Items"];
}
});
}]);
app.factory('User', [function(){
return {
isAuthenticated: false
};
}]);
app.factory('RouteValidator', ['$rootScope', 'User', '$state', function($rootScope, User, $state){
return {
init: init
};
/////////////////////////////////
function init(){
$rootScope.$on('$stateChangeStart', _onStateChangeStart);
}
function _onStateChangeStart(event, toState, toParams, fromState, fromParams){
var toStateRequiresAuth = _requiresAuth(toState);
if(!User.isAuthenticated && toStateRequiresAuth){
event.preventDefault();
$state.go('public');
alert('You are not authorised to see this view');
return;
}
}
function _requiresAuth(toState){
if(angular.isUndefined(toState.data) || !toState.data.requiresAuth){
return false;
}
return toState.data.requiresAuth;
}
}]);
app.run(['RouteValidator', function(RouteValidator){
RouteValidator.init();
}]);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
});
<强>的index.html 强>
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.4.x" src="https://code.angularjs.org/1.4.2/angular.js" data-semver="1.4.2"></script>
<script data-require="ui-router@0.2.15" data-semver="0.2.15" src="//rawgit.com/angular-ui/ui-router/0.2.15/release/angular-ui-router.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<a ui-sref="public">public</a>
<a ui-sref="login">login</a>
<a ui-sref="admin">admin</a>
<div ui-view></div>
</body>
</html>