我在这里阅读文档,不确定我理解所有/和选项之间的区别:https://github.com/fastify/fastify-auth
似乎如果你使用{ relation: 'and' }
,你会在{ run: 'all' }
得到相同的结果。
他们是说{ run: 'all' }
不会改变和/或逻辑,但无论如何它都会运行所有的功能吗?如果这就是它的作用,我不确定我是否理解了那里的用例。即使在确定要继续执行请求之后,您还想继续运行更多代码吗?
似乎如果你使用{relation: '和'}你会得到相同的结果在{run: 'all'}
不,因为relation: and
将停止执行每当一个验证函数不成功,同时run: all
将执行所有的验证函数,无论结果是什么。
你想继续运行更多的代码,即使你已经决定你将继续请求,无论如何?
一个真实的用例是:
- 您支持多种自定义认证类型(从头部读取,从cookie读取或从正文读取)
- 每个auth函数在进行重操作(解密)后向
request
对象添加一些数据
现在,如果您有一些支持由认证用户或服务器到服务器令牌调用的端点,并且您正在从数据库中读取额外的用户角色,如果您没有运行所有的认证函数:
- 授权用户将获得
server token not valid
- 服务器将获得
user token not valid
- 设置
relation: or
将跳过从数据库读取用户数据的验证函数
所以,为了:
- 保持单一的
route
定义 - 不要在所有端点上复制
readFromDb
- 将令牌解密一次
run: all
选项是必需的。
计数器:
- 你需要运行
if (!req.auth)
检查,在你的处理程序
你想继续运行更多的代码,即使你已经确定你将继续请求,无论如何?
是的,你是对的,但正如在应用程序上下文中所说的,如果必须完成作业,则执行布尔检查的函数(例如:if(req.headers.token)
)与一次获取令牌数据的必要性相比毫无意义,并且不复制从db读取用户的代码(因为它是复杂的,由于遗留规则)。
fastify.route({
method: 'GET',
url: '/',
preHandler: fastify.auth([
function authUserToken (request, reply, done) {
if (validUserAuth(request.headers.authorization)) {
request.auth = { from: 'header' }
done()
} else {
done(new Error('you shall not pass'))
}
},
function authServerToken (request, reply, done) {
if (validServerAuth(request.headers['x-auth-s2s'])) {
request.auth = { from: 'server' }
done()
} else {
done(new Error('you shall not pass'))
}
},
function authAugmentation (request, reply, done) {
if (request.auth?.from === 'header') {
request.auth = { from: 'server', user: readFromDb() }
}
done()
}
], { run: 'all' }),
handler: (req, reply) => {
if (!req.auth) {
return reply.send(new Error('auth failed'))
}
return reply.send({ hello: 'world' })
}
})