我正在开发一个基于mean.js锅炉板的应用程序。在这个应用程序中,我需要能够显示/隐藏某些路线/菜单项的基础上,登录用户是否有一个特定的角色。我不确定这是在快车边还是角边更好。例如,如果我有两个顶级菜单项:公共任务和管理任务,而我只想向那些具有管理角色的人展示管理任务。有人做过这样的事吗?
发布于 2015-06-29 21:13:04
事实证明,这非常简单:只需将一个显式的'myRole‘元素添加到.client.config文件中的Menus.addMenuItem行。那里有许多位置参数,因此,一旦我真正地阅读了mean.js文档,就会在那里显式地指定它。在Menus.addMenuItem中,我们对命名、位置、允许的角色等都有完全的控制。我除了确保我的用户在mongodb用户集合中确实有这样的角色之外,还没有做任何其他的事情。
发布于 2015-06-28 15:28:10
您必须同时使用服务器和客户端来完成这一任务。
服务器将维护一个会话跟踪您是谁(id和您的角色,无论是管理员、用户还是仅仅是来宾),并将加密的令牌发送到客户端,客户端将将其存储在cookie中,并在每次发出请求时将其发送回服务器。
此外,您还必须在服务器端照顾您的API路由。我已经从DaftMonk/发电机-角满堆栈的演示应用程序复制了相关的代码。你应该通过下面的代码。
客户端:
代码负责在每个请求中向服务器发送令牌: (链接)
.factory('authInterceptor', function ($rootScope, $q, $cookieStore, $location) {
return {
// Add authorization token to headers
request: function (config) {
config.headers = config.headers || {};
if ($cookieStore.get('token')) {
config.headers.Authorization = 'Bearer ' + $cookieStore.get('token');
}
return config;
},
// Intercept 401s and redirect you to login
responseError: function(response) {
if(response.status === 401) {
$location.path('/login');
// remove any stale tokens
$cookieStore.remove('token');
return $q.reject(response);
}
else {
return $q.reject(response);
}
}
};
Auth: (链接)在客户端处理身份验证。登录后将令牌存储到cookie中,从服务器获取用户详细信息。
angular.module('demoApp')
.factory('Auth', function Auth($location, $rootScope, $http, User, $cookieStore, $q) {
var currentUser = {};
if($cookieStore.get('token')) {
currentUser = User.get();
}
return {
/**
* Authenticate user and save token
*
* @param {Object} user - login info
* @param {Function} callback - optional
* @return {Promise}
*/
login: function(user, callback) {
var cb = callback || angular.noop;
var deferred = $q.defer();
$http.post('/auth/local', {
email: user.email,
password: user.password
}).
success(function(data) {
$cookieStore.put('token', data.token);
currentUser = User.get();
deferred.resolve(data);
return cb();
}).
error(function(err) {
this.logout();
deferred.reject(err);
return cb(err);
}.bind(this));
return deferred.promise;
},
/**
* Delete access token and user info
*
* @param {Function}
*/
logout: function() {
$cookieStore.remove('token');
currentUser = {};
},
/**
* Gets all available info on authenticated user
*
* @return {Object} user
*/
getCurrentUser: function() {
return currentUser;
},
/**
* Check if a user is logged in
*
* @return {Boolean}
*/
isLoggedIn: function() {
return currentUser.hasOwnProperty('role');
},
/**
* Waits for currentUser to resolve before checking if user is logged in
*/
isLoggedInAsync: function(cb) {
if(currentUser.hasOwnProperty('$promise')) {
currentUser.$promise.then(function() {
cb(true);
}).catch(function() {
cb(false);
});
} else if(currentUser.hasOwnProperty('role')) {
cb(true);
} else {
cb(false);
}
},
/**
* Check if a user is an admin
*
* @return {Boolean}
*/
isAdmin: function() {
return currentUser.role === 'admin';
},
/**
* Get auth token
*/
getToken: function() {
return $cookieStore.get('token');
}
};
});
用户Facotry: (链接),当get被调用时,服务器将返回用户的详细信息(名称、角色、其他详细信息)。(/api/user/me)
angular.module('demoApp')
.factory('User', function ($resource) {
return $resource('/api/users/:id/:controller', {
id: '@_id'
},
{
get: {
method: 'GET',
params: {
id:'me'
}
}
});
});
<li ng-show="isLoggedIn()"><a href="/settings">Client Aera</a></li>
<li ng-show="isAdmin()"><a href="/admin">Admin Aera</a></li>
服务器端:
服务器上的Auth: (链接)此代码段处理用于登录路由的POST请求(此处/api/auth/链接)
router.post('/', function(req, res, next) {
passport.authenticate('local', function (err, user, info) {
var error = err || info;
if (error) return res.json(401, error);
if (!user) return res.json(404, {message: 'Something went wrong, please try again.'});
var token = auth.signToken(user._id, user.role);
res.json({token: token});
})(req, res, next)
});
https://stackoverflow.com/questions/31100974
复制相似问题