我有一个应用程序,我使用Cookie来存储访问令牌,并使用API getUser(accessToken)
获取用户详细信息。考虑用户已登录并且我在cookie中有访问令牌但没有用户详细信息的情况。当用户尝试访问某个页面时,请说/ abc,我应该如何解决该问题
这是我在做什么,
我在运行块中有getUser(accessToken)API。我还在运行块中有$rootScope.$on('$stateChangeStart', fuction(){});
之类的事件。
当用户尝试访问/ abc时,我决定检查用户角色以确认用户是否有权访问此页面。在我获得getUser()API的响应之前,我会检查用户角色。
我该如何解决这个问题?
答案 0 :(得分:0)
我认为使用用户角色是最好的选择。 您可以将用户角色实现为常量,如下所示:
.constant('USER_ROLES', {
all: '*',
admin: 'admin',
editor: 'editor',
guest: 'guest'
})
关于常量的一个好处是它们可以像服务一样注入,这使得它们很容易在单元测试中进行模拟。它还允许您以后轻松地重命名它们(更改值),而无需更改大量文件。
与授权(访问控制)相关的逻辑最好分组在服务中:
.factory('AuthService', function ($http, Session) {
var authService = {};
authService.login = function (credentials) {
return $http
.post('/login', credentials)
.then(function (res) {
Session.create(res.data.id, res.data.user.id,
res.data.user.role);
return res.data.user;
});
};
authService.isAuthenticated = function () {
return !!Session.userId;
};
authService.isAuthorized = function (authorizedRoles) {
if (!angular.isArray(authorizedRoles)) {
authorizedRoles = [authorizedRoles];
}
return (authService.isAuthenticated() &&
authorizedRoles.indexOf(Session.userRole) !== -1);
};
return authService;
})
大多数情况下,您不希望访问整个页面而不是隐藏单个元素。使用路由上的自定义数据对象(或状态,使用UI路由器时),我们可以指定应允许哪些角色访问。此示例使用UI路由器样式,但同样适用于ngRoute。
.config(function ($stateProvider, USER_ROLES) {
$stateProvider.state('dashboard', {
url: '/dashboard',
templateUrl: 'dashboard/index.html',
data: {
authorizedRoles: [USER_ROLES.admin, USER_ROLES.editor]
}
});
})
接下来,我们需要在每次路径更改时检查此属性(即用户导航到另一个页面)。这涉及监听$ routeChangeStart(对于ngRoute)或$ stateChangeStart(对于UI路由器)事件:
.run(function ($rootScope, AUTH_EVENTS, AuthService) {
$rootScope.$on('$stateChangeStart', function (event, next) {
var authorizedRoles = next.data.authorizedRoles;
if (!AuthService.isAuthorized(authorizedRoles)) {
event.preventDefault();
if (AuthService.isAuthenticated()) {
// user is not allowed
$rootScope.$broadcast(AUTH_EVENTS.notAuthorized);
} else {
// user is not logged in
$rootScope.$broadcast(AUTH_EVENTS.notAuthenticated);
}
}
});
})
如果用户未被授权访问该页面(因为他未登录或没有正确的角色),将阻止转换到下一页,因此用户将保留在当前页面上。 / p>