我有一个用yeoman,grunt和bower创建的AngularJS应用程序。
我有一个登录页面,它有一个检查身份验证的控制器。如果凭据是正确的,我会重新路由到主页。
app.js
'use strict';
//Define Routing for app
angular.module('myApp', []).config(['$routeProvider', '$locationProvider',
function($routeProvider,$locationProvider) {
$routeProvider
.when('/login', {
templateUrl: 'login.html',
controller: 'LoginController'
})
.when('/register', {
templateUrl: 'register.html',
controller: 'RegisterController'
})
.when('/forgotPassword', {
templateUrl: 'forgotpassword.html',
controller: 'forgotController'
})
.when('/home', {
templateUrl: 'views/home.html',
controller: 'homeController'
})
.otherwise({
redirectTo: '/login'
});
// $locationProvider.html5Mode(true); //Remove the '#' from URL.
}]);
angular.module('myApp').factory("page", function($rootScope){
var page={};
var user={};
page.setPage=function(title,bodyClass){
$rootScope.pageTitle = title;
$rootScope.bodylayout=bodyClass;
};
page.setUser=function(user){
$rootScope.user=user;
}
return page;
});
LoginControler.js
'use strict';
angular.module('myApp').controller('LoginController', function($scope, $location, $window,page) {
page.setPage("Login","login-layout");
$scope.user = {};
$scope.loginUser=function()
{
var username=$scope.user.name;
var password=$scope.user.password;
if(username=="admin" && password=="admin123")
{
page.setUser($scope.user);
$location.path( "/home" );
}
else
{
$scope.message="Error";
$scope.messagecolor="alert alert-danger";
}
}
});
在我的主页上
<span class="user-info">
<small>Welcome,</small>
{{user.name}}
</span>
<span class="logout"><a href="" ng-click="logoutUser()">Logout</a></span>
在loginController
中,我检查登录信息,如果成功,就在服务工厂中设置user对象。我不知道这是对是错。
我需要的是,当用户登录时,它在user对象中设置一些值,以便所有其他页面都可以获得该值。
每当发生任何路由更改时,控制器都应该检查用户是否登录。如果不是,它应该重新路由到登录页面。此外,如果用户已经登录并返回到页面,它应该转到主页。控制器还应该检查所有路由上的凭证。
我听说过ng-cookie,但我不知道如何使用它们。
我看到的许多示例都不是很清楚,它们使用了某种访问角色或其他什么。我不想这样。我只想要一个登录过滤器。有没有人能给我一些建议?
发布于 2014-01-07 20:22:56
我的解决方案分为三个部分:用户的状态存储在服务中,在run方法中,当路由发生变化时,您可以查看用户是否被允许访问请求的页面,在主控制器中,您可以查看用户的状态是否发生了变化。
app.run(['$rootScope', '$location', 'Auth', function ($rootScope, $location, Auth) {
$rootScope.$on('$routeChangeStart', function (event) {
if (!Auth.isLoggedIn()) {
console.log('DENY');
event.preventDefault();
$location.path('/login');
}
else {
console.log('ALLOW');
$location.path('/home');
}
});
}]);
您应该创建一个服务(我将其命名为Auth
),该服务将处理user对象,并具有一个方法来了解用户是否已登录。
服务
.factory('Auth', function(){
var user;
return{
setUser : function(aUser){
user = aUser;
},
isLoggedIn : function(){
return(user)? user : false;
}
}
})
在您的app.run
中,您应该监听$routeChangeStart
事件。当路由更改时,它将检查用户是否已登录( isLoggedIn
方法应处理此问题)。如果用户没有登录,它不会加载请求的路由,它会将用户重定向到正确的页面(在您的情况下是登录)。
应该在登录页面中使用loginController
来处理登录。它应该只是与Auth
服务交互,并将用户设置为已登录或未登录。
loginController
.controller('loginCtrl', [ '$scope', 'Auth', function ($scope, Auth) {
//submit
$scope.login = function () {
// Ask to the server, do your job and THEN set the user
Auth.setUser(user); //Update the state of the user in the app
};
}])
在主控制器中,您可以监听用户状态是否发生更改,并通过重定向做出反应。
.controller('mainCtrl', ['$scope', 'Auth', '$location', function ($scope, Auth, $location) {
$scope.$watch(Auth.isLoggedIn, function (value, oldValue) {
if(!value && oldValue) {
console.log("Disconnect");
$location.path('/login');
}
if(value) {
console.log("Connect");
//Do something when the user is connected
}
}, true);
发布于 2015-04-22 20:09:47
这是另一种可能的解决方案,使用$stateProvider
或$routeProvider
的resolve
属性。使用$stateProvider
的示例
.config(["$stateProvider", function ($stateProvider) {
$stateProvider
.state("forbidden", {
/* ... */
})
.state("signIn", {
/* ... */
resolve: {
access: ["Access", function (Access) { return Access.isAnonymous(); }],
}
})
.state("home", {
/* ... */
resolve: {
access: ["Access", function (Access) { return Access.isAuthenticated(); }],
}
})
.state("admin", {
/* ... */
resolve: {
access: ["Access", function (Access) { return Access.hasRole("ROLE_ADMIN"); }],
}
});
}])
Access
根据当前用户权限解决或拒绝承诺:
.factory("Access", ["$q", "UserProfile", function ($q, UserProfile) {
var Access = {
OK: 200,
// "we don't know who you are, so we can't say if you're authorized to access
// this resource or not yet, please sign in first"
UNAUTHORIZED: 401,
// "we know who you are, and your profile does not allow you to access this resource"
FORBIDDEN: 403,
hasRole: function (role) {
return UserProfile.then(function (userProfile) {
if (userProfile.$hasRole(role)) {
return Access.OK;
} else if (userProfile.$isAnonymous()) {
return $q.reject(Access.UNAUTHORIZED);
} else {
return $q.reject(Access.FORBIDDEN);
}
});
},
hasAnyRole: function (roles) {
return UserProfile.then(function (userProfile) {
if (userProfile.$hasAnyRole(roles)) {
return Access.OK;
} else if (userProfile.$isAnonymous()) {
return $q.reject(Access.UNAUTHORIZED);
} else {
return $q.reject(Access.FORBIDDEN);
}
});
},
isAnonymous: function () {
return UserProfile.then(function (userProfile) {
if (userProfile.$isAnonymous()) {
return Access.OK;
} else {
return $q.reject(Access.FORBIDDEN);
}
});
},
isAuthenticated: function () {
return UserProfile.then(function (userProfile) {
if (userProfile.$isAuthenticated()) {
return Access.OK;
} else {
return $q.reject(Access.UNAUTHORIZED);
}
});
}
};
return Access;
}])
UserProfile
复制当前的用户属性,并实现$hasRole
、$hasAnyRole
、$isAnonymous
和$isAuthenticated
方法逻辑(以及稍后解释的$refresh
方法):
.factory("UserProfile", ["Auth", function (Auth) {
var userProfile = {};
var clearUserProfile = function () {
for (var prop in userProfile) {
if (userProfile.hasOwnProperty(prop)) {
delete userProfile[prop];
}
}
};
var fetchUserProfile = function () {
return Auth.getProfile().then(function (response) {
clearUserProfile();
return angular.extend(userProfile, response.data, {
$refresh: fetchUserProfile,
$hasRole: function (role) {
return userProfile.roles.indexOf(role) >= 0;
},
$hasAnyRole: function (roles) {
return !!userProfile.roles.filter(function (role) {
return roles.indexOf(role) >= 0;
}).length;
},
$isAnonymous: function () {
return userProfile.anonymous;
},
$isAuthenticated: function () {
return !userProfile.anonymous;
}
});
});
};
return fetchUserProfile();
}])
Auth
负责请求服务器,以了解用户配置文件(例如,链接到附加到请求的访问令牌):
.service("Auth", ["$http", function ($http) {
this.getProfile = function () {
return $http.get("api/auth");
};
}])
服务器需要在请求GET api/auth
时返回这样的JSON对象。
{
"name": "John Doe", // plus any other user information
"roles": ["ROLE_ADMIN", "ROLE_USER"], // or any other role (or no role at all, i.e. an empty array)
"anonymous": false // or true
}
最后,如果使用ui.router
,当Access
拒绝一个promise时,将触发$stateChangeError
事件:
.run(["$rootScope", "Access", "$state", "$log", function ($rootScope, Access, $state, $log) {
$rootScope.$on("$stateChangeError", function (event, toState, toParams, fromState, fromParams, error) {
switch (error) {
case Access.UNAUTHORIZED:
$state.go("signIn");
break;
case Access.FORBIDDEN:
$state.go("forbidden");
break;
default:
$log.warn("$stateChangeError event catched");
break;
}
});
}])
如果使用ngRoute
,将触发$routeChangeError
事件:
.run(["$rootScope", "Access", "$location", "$log", function ($rootScope, Access, $location, $log) {
$rootScope.$on("$routeChangeError", function (event, current, previous, rejection) {
switch (rejection) {
case Access.UNAUTHORIZED:
$location.path("/signin");
break;
case Access.FORBIDDEN:
$location.path("/forbidden");
break;
default:
$log.warn("$stateChangeError event catched");
break;
}
});
}])
还可以在控制器中访问用户配置文件:
.state("home", {
/* ... */
controller: "HomeController",
resolve: {
userProfile: "UserProfile"
}
})
然后,UserProfile
包含服务器在请求GET api/auth
时返回的属性
.controller("HomeController", ["$scope", "userProfile", function ($scope, userProfile) {
$scope.title = "Hello " + userProfile.name; // "Hello John Doe" in the example
}])
当用户登录或注销时,需要刷新UserProfile
,以便Access
可以使用新的用户配置文件处理路由。您可以重新加载整个页面,也可以调用UserProfile.$refresh()
。登录时的示例:
.service("Auth", ["$http", function ($http) {
/* ... */
this.signIn = function (credentials) {
return $http.post("api/auth", credentials).then(function (response) {
// authentication succeeded, store the response access token somewhere (if any)
});
};
}])
.state("signIn", {
/* ... */
controller: "SignInController",
resolve: {
/* ... */
userProfile: "UserProfile"
}
})
.controller("SignInController", ["$scope", "$state", "Auth", "userProfile", function ($scope, $state, Auth, userProfile) {
$scope.signIn = function () {
Auth.signIn($scope.credentials).then(function () {
// user successfully authenticated, refresh UserProfile
return userProfile.$refresh();
}).then(function () {
// UserProfile is refreshed, redirect user somewhere
$state.go("home");
});
};
}])
发布于 2016-07-11 09:23:42
定义单个路由的自定义行为的最直接方式将非常简单:
1)为routes.js
**:创建一个新属性(如** requireAuth
**) **
angular.module('yourApp').config(function($routeProvider) {
$routeProvider
.when('/home', {
templateUrl: 'templates/home.html',
requireAuth: true // our custom property
})
.when('/login', {
templateUrl: 'templates/login.html',
})
.otherwise({
redirectTo: '/home'
});
})
代码2)在未绑定到angular ng-view
$routeProvider
内部元素的顶级控制器中(为避免与ng-view$routeProvider
冲突),检查是否具有属性并采取相应操作<>E230
angular.module('YourApp').controller('YourController', function ($scope, $location, session) {
// intercept the route change event
$scope.$on('$routeChangeStart', function (angularEvent, newUrl) {
// check if the custom property exist
if (newUrl.requireAuth && !session.user) {
// user isn’t authenticated
$location.path("/login");
}
});
});
https://stackoverflow.com/questions/20969835
复制相似问题