Node.js:授权路由与授权方法

时间:2018-06-26 08:44:55

标签: node.js express session mongoose authorization

快速背景

我正在使用Node.jsExpressMongoose构建API。我实现的身份验证可与passport-headerapikey包一起使用。我使用api键在数据库中搜索该用户,并将该用户添加到req对象中。从而确保我一直对身份了解到请求结束。

授权

让我们解决这个问题。

到目前为止,在执行任何操作之前,我在每个端点中手动调用了authorize() function。像这样:

router.post('/', (req, res) => {
  autorize('admin', req.user.role) // method is called at every route manually
    .then(() => {
      ... do stuff here 
    })
    .catch(err => req.status(403).send())
}

我的同事对我说,这不是一个好的解决方案,而不仅仅是保护端点本身,我应该拥有一个会话管理,使当前用户在全球范围内可用,以便我可以随时随地在功能

含义: 然后,方法createUser(obj)可以在其内部调用授权方法或检查条件,如下所示:

createUser(obj) {
  if (currentUser.role !== 'admin') {
    return false        
  }

  obj = new User(obj)
  return obj.save()
}

这意味着如果满足条件,我将在每个函数中return false。访问该会话的全局可用currentUser。 (例如globalCurrentUser.role !== admin或类似的内容)

我的问题

  1. 仅保护端点而不保护功能是否是错误的做法?
  2. 我是否可以仅对每个函数都要求一个额外的参数“ auth”,以便在调用该函数时需要像在我的currentUser.role函数中那样接收authorize()或它返回false?这意味着我将用户手动传递给每个函数,否则它将失败
  3. 如果在请求期间我应该对用户的全局访问进行会话管理:您对框架有建议吗?

预先感谢, 本诺

1 个答案:

答案 0 :(得分:0)

身份验证和授权是两个不同的事物,应分开对待。身份验证显示“您是谁?”授权显示“您有权限吗?”。考虑到Express是完全围绕中间件设计的,我将执行以下操作。

  1. 在安装路由器/路由之前,将身份验证抽象为一个中间件,该中间件将使用app.use()在所有端点上运行。
  2. 创建一个可以在任何地方调用的授权函数,它需要一个用户(或id或您拥有的任何东西)和一个角色,然后检查用户是否具有该角色。

这样想,您的授权将永远不会改变,这是您应用程序的核心。如果您决定放弃Expressjs并使用Koa或从传统的HTTP请求转移到Web套接字,则不需要更改授权逻辑。但是您的身份验证可能会发生变化,您可能不希望再使用标头来存储令牌,或者您完全切换到cookie或其他内容,则可能希望更改它。

您最终会得到一块全局中间件,该中间件检查auth令牌并将user对象附加到req。然后,您将获得一个名为userHasRole之类的实用程序函数,该函数将在需要在应用程序中具有特定角色的任何端点处调用。然后,您可以随时在应用程序中的任何位置检查权限。这可能在整个应用程序中的不同位置,例如,在对某些管理仪表板的请求开始时,您可能会检查他们是否是管理员,但是如果他们尝试访问特定资源,则可能稍后再检查权限。访问特定资源时,您可能希望让他们通过,并在最后一分钟确定他们是否有权访问该资源。 (在不了解您的应用程序的情况下很难给出具体示例。)

在某些情况下,可能需要在业务逻辑的开头进行检查,而在其他地方,稍后进行检查可能是有意义的。没关系,您应该可以在需要时运行此检查。这将完全取决于业务逻辑,并且如果仅格式化字符串输出,将其放置在每个函数中可能就没用了,但是在尝试提取数据库记录时可能很有用。