我正在使用Node.js
,Express
和Mongoose
构建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
或类似的内容)
currentUser.role
函数中那样接收authorize()
或它返回false?这意味着我将用户手动传递给每个函数,否则它将失败预先感谢, 本诺
答案 0 :(得分:0)
身份验证和授权是两个不同的事物,应分开对待。身份验证显示“您是谁?”授权显示“您有权限吗?”。考虑到Express是完全围绕中间件设计的,我将执行以下操作。
app.use()
在所有端点上运行。这样想,您的授权将永远不会改变,这是您应用程序的核心。如果您决定放弃Expressjs并使用Koa或从传统的HTTP请求转移到Web套接字,则不需要更改授权逻辑。但是您的身份验证可能会发生变化,您可能不希望再使用标头来存储令牌,或者您完全切换到cookie或其他内容,则可能希望更改它。
您最终会得到一块全局中间件,该中间件检查auth令牌并将user
对象附加到req
。然后,您将获得一个名为userHasRole
之类的实用程序函数,该函数将在需要在应用程序中具有特定角色的任何端点处调用。然后,您可以随时在应用程序中的任何位置检查权限。这可能在整个应用程序中的不同位置,例如,在对某些管理仪表板的请求开始时,您可能会检查他们是否是管理员,但是如果他们尝试访问特定资源,则可能稍后再检查权限。访问特定资源时,您可能希望让他们通过,并在最后一分钟确定他们是否有权访问该资源。 (在不了解您的应用程序的情况下很难给出具体示例。)
在某些情况下,可能需要在业务逻辑的开头进行检查,而在其他地方,稍后进行检查可能是有意义的。没关系,您应该可以在需要时运行此检查。这将完全取决于业务逻辑,并且如果仅格式化字符串输出,将其放置在每个函数中可能就没用了,但是在尝试提取数据库记录时可能很有用。