如何 show/hide 根据用户在 mean.js 应用程序中的角色进行路由
How to show/hide routes based on the user's role in a mean.js application
我正在构建一个基于 mean.js 样板的应用程序。在此应用中,我需要能够根据登录用户是否具有特定角色 show/hide 某些 routes/menu 项目。我不确定这是在快递方面还是 angular 方面做得更好。例如,如果我有两个顶级菜单项:普通任务和管理任务,我只想向具有管理员角色的人显示管理任务。有人做过这样的事吗?
您必须同时使用服务器和客户端来做到这一点。
服务器将在设定的时间内保持会话跟踪您的身份(ID 和您的角色,无论是管理员、用户还是访客),并向客户端发送加密令牌,客户端会将其存储在 cookie 中并发送每次发出请求时它都会返回服务器。
- 例如,您可以使用 JWT 等 express-jwt 中间件作为 express。
- & Passportjs 用于身份验证。
您还必须在服务器端照顾您的 API 路由。我已经从 DaftMonk/generator-angular-fullstack's demo app 复制了相关代码。你应该通过下面的代码。
客户端:
负责在每个请求中向服务器发送令牌的代码: (link)
.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);
}
}
};
授权工厂: (link)
在客户端处理身份验证。登录后将令牌存储到 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');
}
};
});
用户工厂: (link)
当调用 get 时,服务器将 return 用户的详细信息(名称、角色、其他详细信息)。 (/api/users/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>
服务器端:
服务器上的身份验证: (link)
此代码段处理 POST 登录路由请求(此处 /api/auth/local)
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)
});
事实证明这非常简单:只需在 .client.config 文件的 Menus.addMenuItem 行中添加一个明确的 ['myRole'] 元素。那里有许多位置参数,所以,一旦我真的费心阅读 mean.js 文档,它就在那里被明确指定。在 Menus.addMenuItem 中,我们可以完全控制命名、职位、允许的角色等......除了确保我的用户在 mongodb 用户合集
我正在构建一个基于 mean.js 样板的应用程序。在此应用中,我需要能够根据登录用户是否具有特定角色 show/hide 某些 routes/menu 项目。我不确定这是在快递方面还是 angular 方面做得更好。例如,如果我有两个顶级菜单项:普通任务和管理任务,我只想向具有管理员角色的人显示管理任务。有人做过这样的事吗?
您必须同时使用服务器和客户端来做到这一点。
服务器将在设定的时间内保持会话跟踪您的身份(ID 和您的角色,无论是管理员、用户还是访客),并向客户端发送加密令牌,客户端会将其存储在 cookie 中并发送每次发出请求时它都会返回服务器。
- 例如,您可以使用 JWT 等 express-jwt 中间件作为 express。
- & Passportjs 用于身份验证。
您还必须在服务器端照顾您的 API 路由。我已经从 DaftMonk/generator-angular-fullstack's demo app 复制了相关代码。你应该通过下面的代码。
客户端:
负责在每个请求中向服务器发送令牌的代码: (link)
.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);
}
}
};
授权工厂: (link) 在客户端处理身份验证。登录后将令牌存储到 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');
}
};
});
用户工厂: (link) 当调用 get 时,服务器将 return 用户的详细信息(名称、角色、其他详细信息)。 (/api/users/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>
服务器端:
服务器上的身份验证: (link) 此代码段处理 POST 登录路由请求(此处 /api/auth/local)
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)
});
事实证明这非常简单:只需在 .client.config 文件的 Menus.addMenuItem 行中添加一个明确的 ['myRole'] 元素。那里有许多位置参数,所以,一旦我真的费心阅读 mean.js 文档,它就在那里被明确指定。在 Menus.addMenuItem 中,我们可以完全控制命名、职位、允许的角色等......除了确保我的用户在 mongodb 用户合集