Node.js 核实角色及;使用Passport.js进行身份验证

Node.js 核实角色及;使用Passport.js进行身份验证,node.js,express,roles,passport.js,Node.js,Express,Roles,Passport.js,因此,我想在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'); }

因此,我想在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');
    }
})
然而,最终目标是至少向用户呈现一些,即使他们没有使用正确的角色登录或验证

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]);
    }
})
我想我已经知道如何工作了,但我不知道如何指定相同的路由,在请求中没有任何授权头的情况下可能会命中该路由


这在Passport.js/Express中可能吗?

解决方案是限制视图中的内容,而不是路由

router.get('/test', authenticationMiddleware, function(req, res){
    var premiumFlag = req.user.role;
    res.send('premiumontent', {role: premiumFlag});
});
premiumContent.jade

p This content is visible to all users

- if role === "premium"
    p this content is only visible to premium users

对于我的答案,我找到的解决方案是使用文档的改编

在我需要返回数据的路由中,无论用户是否登录,我都可以使用以下方法:

// 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);
});

我建议您使用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);
});
免责声明:我在工作,我们在API身份验证和设计方面花了很多心思,我们对这个主题有一个真正的介绍:


您必须构建自己的fork-in-or,以允许这一点,我相信fork-in-or-the-passport-repo并添加该功能,这就是您的意思吗?我认为应该是这个。如果你正在使用它。你应该看一看这些台词,我明白了,当然,绝对值得一看。然而,我认为我需要提供另一个检查器,因为在某些内容上,如果人们没有授权,我仍然希望将他们踢出(就像默认情况一样)。然后,您的passport中间件的修改版本可能应该查看当前路由,如果它与特定的正则表达式匹配,则踢出。当然,如果使用jade,那么res.send(401)仍然是一个很好的解决方案。如果我不用翡翠怎么办?我想把这些路由严格地保存在API上。如果你正在构建API,你应该编辑这个问题,这样我们就可以提供特定于API的答案:)Jade真的那么普遍地认为它是在NodeJS应用程序中实现的吗,尽管如此?我猜这是NodeJ最常用的模板引擎,但不管它们有多相似,都可以很容易地将示例从Jade翻译成其他任何一个。好主意!然而,任何未登录并在其流中看到高级内容的用户都会在其控制台中出现错误,对吗?这是一种良好的常规做法吗?特别是如果angular应用程序正在侦听错误代码并使用其他路由/模板进行响应?您的客户端(angular应用程序等)确实需要读取这些状态代码或错误消息并相应地响应-如何向客户端用户显示。。这完全取决于你:)