node.js 使用 Passport.js 验证角色和身份验证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26895219/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Verifying roles & authentication with Passport.js
提问by
So I'd like to make some routes in an API that will show different data based on the user role, defined in MongoDB. Here's a sampling of what I have right now, it works...
所以我想在 API 中创建一些路由,这些路由将根据 MongoDB 中定义的用户角色显示不同的数据。这是我现在拥有的样本,它有效......
router.get('/test', passport.authenticate('bearer', {session: false}), function (req, res) {
if (req.user.role == "premium") {
return res.send('you can see this content');
}
else {
return res.send('you can not see this content');
}
})
However, the end goal is to present at least somethingto the user, even if they're not logged in or authenticated with the right kind of role.
然而,最终目标是至少向用户展示一些东西,即使他们没有登录或使用正确的角色进行身份验证。
router.get('/test', passport.authenticate('bearer', {session: false}), function (req, res) {
if (req.user.role == "premium") {
return res.send('this is premium content');
}
else {
// could be hit by another role, or no user at all
return res.send([some truncated version of the premium content]);
}
})
Which I would think I'd figure out how to work, but I don't know how to specify the same route which possibly could be hit without any Authorization header in the request.
我想我会弄清楚如何工作,但我不知道如何指定相同的路由,该路由可能在请求中没有任何 Authorization 标头的情况下被命中。
Is this possible in Passport.js/Express?
这在 Passport.js/Express 中可行吗?
采纳答案by robertjd
I would suggest that you use HTTP status codes and an error object, this is a common API convention and it allows your API users to know what's happening and why:
我建议您使用 HTTP 状态代码和错误对象,这是一个常见的 API 约定,它允许您的 API 用户知道发生了什么以及为什么:
app.get('/premium-resource', function(req, res, next) {
passport.authenticate('bearer', function(err, user) {
if (user){
if (user.role === 'premium'){
return res.send(200,{userContent:'you are a premium user'});
}else{
return res.send(403,{
'status': 403,
'code': 1, // custom code that makes sense for your application
'message': 'You are not a premium user',
'moreInfo': 'https://myawesomeapi.io/upgrade'
});
}
}else{
return res.send(401,{
'status': 401,
'code': 2, // custom code that makes sense for your application
'message': 'You are not authenticated.',
'moreInfo': 'https://myawesomeapi.io/docs'
});
}
})(req, res, next);
});
Disclaimer: I work at Stormpathand we put a lot of thought into API authentication and design, we have a really presentation on the topic:
免责声明:我在Stormpath工作,我们在 API 身份验证和设计方面投入了大量精力,我们有一个关于该主题的真实演示:
回答by takinola
The solution is to limit the content in the view rather than the route.
解决办法是限制视图中的内容而不是路由。
router.get('/test', authenticationMiddleware, function(req, res){
var premiumFlag = req.user.role;
res.send('premiumontent', {role: premiumFlag});
});
premiumContent.jade
优质内容.jade
p This content is visible to all users
- if role === "premium"
p this content is only visible to premium users
回答by takinola
The solution I've found to my answer is to use an adaptation of the Passportjs.orgdocumentation.
我找到的答案的解决方案是使用Passportjs.org文档的改编版本。
In the routes I need to return data, whether a user is logged in or not I can use something like:
在我需要返回数据的路由中,无论用户是否登录,我都可以使用以下内容:
// Test to check for authentication
app.get('/login', function(req, res, next) {
passport.authenticate('bearer', function(err, user, info) {
if (user)
// check user's role for premium or not
if (user.role == "premium")
return res.send('user is premium')
else
return res.send('user is not premium');
else
// return items even if no authentication is present, instead of 401 response
return res.send('not logged in');
})(req, res, next);
});

