@ fastify/ auth (帮助)
本模块不提供认证策略,而是在不增加间接费用的情况下快速用于处理路由中的认证和多策略. 见一个完整的例子 这里。 。 。 .
安装
npm i @fastify/auth
兼容性
| 插件版本 | 快速化版本 |
|---|---|
>=5.x | ^5.x |
>=3.x <5.x | ^4.x |
>=1.x <3.x | ^3.x |
^0.x | ^2.x |
^0.x | ^1.x |
请注意,如果一个快取版本没有支持,那么该插件的相应版本也一样 上表列出. 见 快速化 LTS 政策 更多细节.
使用量
@fastify/auth 不提供认证策略; 认证策略必须使用装饰器或其他插件提供.
以下例子为显示本单元的使用提供了直接的实施:
fastify
.decorate('verifyJWTandLevel', function (request, reply, done) {
// your validation logic
done() // pass an error if the authentication fails
})
.decorate('verifyUserAndPassword', function (request, reply, done) {
// your validation logic
done() // pass an error if the authentication fails
})
.register(require('@fastify/auth'))
.after(() => {
fastify.route({
method: 'POST',
url: '/auth-multiple',
preHandler: fastify.auth([
fastify.verifyJWTandLevel,
fastify.verifyUserAndPassword
]),
handler: (req, reply) => {
req.log.info('Auth route')
reply.send({ hello: 'world' })
}
})
})
这些定制认证策略的默认关系是: or不过 and 也可以使用:
fastify
.decorate('verifyAdmin', function (request, reply, done) {
// your validation logic
done() // pass an error if the authentication fails
})
.decorate('verifyReputation', function (request, reply, done) {
// your validation logic
done() // pass an error if the authentication fails
})
.register(require('@fastify/auth'))
.after(() => {
fastify.route({
method: 'POST',
url: '/auth-multiple',
preHandler: fastify.auth([
fastify.verifyAdmin,
fastify.verifyReputation
], {
relation: 'and'
}),
handler: (req, reply) => {
req.log.info('Auth route')
reply.send({ hello: 'world' })
}
})
})
对于复合认证,如验证用户密码和级别或符合VIP标准,使用嵌入式阵列.
例如,逻辑[(验证用户名词) and 校验等级) or (核查VIP)]可以用以下代码实现:
fastify
.decorate('verifyUserPassword', function (request, reply, done) {
// your validation logic
done() // pass an error if the authentication fails
})
.decorate('verifyLevel', function (request, reply, done) {
// your validation logic
done() // pass an error if the authentication fails
})
.decorate('verifyVIP', function (request, reply, done) {
// your validation logic
done() // pass an error if the authentication fails
})
.register(require('@fastify/auth'))
.after(() => {
fastify.route({
method: 'POST',
url: '/auth-multiple',
preHandler: fastify.auth([
[fastify.verifyUserPassword, fastify.verifyLevel], // The arrays within an array have the opposite relation to the main (default) relation.
fastify.verifyVIP
], {
relation: 'or' // default relation
}),
handler: (req, reply) => {
req.log.info('Auth route')
reply.send({ hello: 'world' })
}
})
})
如果 relation (单位:千美元)defaultRelation参数是 and,那么子阵列内部的关系将是 or。 。 。 .
如果 relation (单位:千美元)defaultRelation参数是 or,那么子阵列内部的关系将是 and。 。 。 .
| 认证代码 | 生成逻辑表达式 |
|---|---|
fastify.auth([f1, f2, [f3, f4]], { relation: 'or' }) | f1 OR f2 OR (f3 AND f4) |
fastify.auth([f1, f2, [f3, f4]], { relation: 'and' }) | f1 AND f2 AND (f3 OR f4) |
这个 defaultRelation 选项可以在注册插件以更改默认值时使用 relation数字 :
fastify.register(require('@fastify/auth'), { defaultRelation: 'and'} )
更多实例请检查 example-composited.js
此插件支持 callbacks 和 Promises 按函数返回。 说明a async 函数 没有 来呼叫 done 参数, 否则, 路由处理器会链接到认证方法 可能会被多次调用数字 :
fastify
.decorate('asyncVerifyJWTandLevel', async function (request, reply) {
// your async validation logic
await validation()
// throws an error if the authentication fails
})
.decorate('asyncVerifyUserAndPassword', function (request, reply) {
// return a promise that throws an error if the authentication fails
return myPromiseValidation()
})
.register(require('@fastify/auth'))
.after(() => {
fastify.route({
method: 'POST',
url: '/auth-multiple',
preHandler: fastify.auth([
fastify.asyncVerifyJWTandLevel,
fastify.asyncVerifyUserAndPassword
]),
handler: (req, reply) => {
req.log.info('Auth route')
reply.send({ hello: 'world' })
}
})
})
路线定义应作为 一个插件 或在内 .after() 调用。 完整的例子见 实例.js。 。 。 .
@fastify/auth 运行所有认证方法,允许请求在至少一个成功的情况下继续;否则,它会返回一个错误给客户端.
任何成功的认证停止 @fastify/auth 不尝试其他的,除非 run: 'all' 提供参数:
fastify.route({
method: 'GET',
url: '/run-all',
preHandler: fastify.auth([
(request, reply, done) => { console.log('executed 1'); done() },
(request, reply, done) => { console.log('executed 2'); done() },
(request, reply, done) => { console.log('executed 3'); done(new Error('you are not authenticated')) },
(request, reply, done) => { console.log('executed 4'); done() },
(request, reply, done) => { console.log('executed 5'); done(new Error('you shall not pass')) }
], { run: 'all' }),
handler: (req, reply) => { reply.send({ hello: 'world' }) }
})
此示例显示所有控制台日志, 并总是以 401: you are not authenticated。 。 。 .
这个 run 参数用于将商业数据从认证符中读取到请求中.
此插件可以像上面的例子一样在路由级别使用,也可以在钩子级别使用 preHandler 钩:
fastify.addHook('preHandler', fastify.auth([
fastify.verifyJWTandLevel,
fastify.verifyUserAndPassword
]))
fastify.route({
method: 'POST',
url: '/auth-multiple',
handler: (req, reply) => {
req.log.info('Auth route')
reply.send({ hello: 'world' })
}
})
这两种方法的不同之处在于使用路由级别 preHandler 函数只运行选定路由的认证,同时使用 preHandler 勾通运行当前插件中的所有路由及其后代的认证.
安全考虑
钩选择
在那个 缩短使用周期,则 onRequest 财务报告和审定财务报表 preParsing 级不剖析有效载荷,不同于 preHandler 阶段。 剖析身体可能是一种潜在的安全风险,因为它可用于拒绝服务(DoS)攻击. 因此,建议避免对尸体进行剖析,以便未经授权进入.
使用 @fastify/auth 插件在单元格中 preHandler 如果恶意用户在请求体中发送出一大笔有效载荷,且请求未经授权,钩子可能导致不必要的内存分配. 快速会解析身体,即使请求没有被授权,导致不必要的内存分配. 为了避免这种情况,请使用 onRequest 或者说 preParsing 如果该方法不需要请求正文, 则用于认证的钩子, 例如 @fastify/jwt,它期望在请求头中认证.
对于需要请求体的认证方法,如在请求体中发送一个符号,使用 preHandler 钩.
在混合情况下,您必须使用 preHandler 钩.
API 密码
选项
@ fastify/ auth (帮助) 接受选项对象 :
{
defaultRelation: 'and'
}
defaultRelation(默认 :or:函数之间的默认关系. 也可以这样or或者说and。 。 。 .
承认
过去提案国:
- 莱兹
许可证
许可证根据 麻省理工学院。 。 。 .