我有一个用 Express JS 编写的中间件,它可以验证从客户端发送的 JWT,如果令牌有效,则返回其有效负载,即编码后的用户:
const authenticateToken = async (req, res, next) => {
try {
const token = req.headers.authentication?.replace('Bearer ', '')
if (!token) return res.status(401).json('Authentication required')
const response = await verifyUserJWT(token)
if (response.status !== 200)
return res.status(response.status).json(response.item)
req.user = response.item
next()
} catch (err) {
return res.status(500).json(err)
}
}
我正在尝试将此代码从 Express 迁移到 Elysia,它仍然很新,并且互联网上没有太多关于它的信息。
这是我迄今为止的进展:
const authenticateToken = async ({headers, set}: any) => {
try {
const token = headers.authentication?.replace('Bearer ', '')
if (!token) {
set.status = 401
return 'Authentication required'
}
const response = await verifyUserJWT(token)
if (response.status !== 200) {
set.status = response.status
return response.item
}
} catch (err) {
set.status = 500
return err
}
}
Elysia 使用钩子而不是中间件(类似的东西),所以我将它用作本地钩子来验证令牌,然后再继续处理路由:
import { Elysia } from 'elysia'
const app = new Elysia()
const PORT: string | 5000 = Bun.env.PORT || 5000
app.get('/', () => return 'Hello, World!', {
beforeHandle: ({set, headers}: any) => {
authenticateToken()
}
})
// Expected result: If authenticateToken() fails, return the error message
// Otherwise proceed with the handler which then returns "Hello, World!"
.listen(PORT)
console.log(
`🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`
)
大部分迁移工作都非常简单,除了我需要从令牌中保存获取的用户的部分,以便下次我可以重用它(例如调用 req.user)而不必再次解码令牌。如果您必须在同一过程中多次执行相同的操作,那么它就违背了快速的整个目的。
为了更好地演示我的意思,这是我的另一个中间件,如果一切顺利,它会在第一个中间件之后立即执行:
const authorizeAdmin = async (req, res, next) => {
try {
if (!req.user) {
return res.status(401).json('Please login first.')
}
if (req.user.role !== 1) {
return res.status(403).json('Unauthorized access.')
}
next()
} catch (err) {
return res.status(500).json(err)
}
}
由于我已经在第一个中定义了 req.user,所以我可以在这里重用它。
我还没有找到任何方法可以在 Elysia 中实现相同的结果,因为文档不是那么好。 ChatGPT 和其他人工智能聊天模型也没有任何信息,因为该技术仍然很新。即使谷歌搜索也没有帮助。
你们知道 Elysia 的 req.user 的等效项或任何替代方案吗?
没关系,其实很简单。就像在 Express 中一样使用 {request}
app.get('/', ({ request }: any) => request.phrase, {
beforeHandle: ({ request }: any) => {
request.phrase = 'Hello, World!'
},
})