Skip to content
On this page

hono-jwt

简介

hono-jwt 是 Hono 框架的 JWT(JSON Web Token)认证中间件,提供了简单而强大的方式来实现基于令牌的身份验证。它支持令牌验证、签名和解码,可以轻松保护 API 路由。

安装

bash
npm install hono @hono/jwt

基本使用

typescript
import { Hono } from 'hono'
import { jwt } from '@hono/jwt'

const app = new Hono()

// JWT 密钥
const JWT_SECRET = 'your-secret-key'

// 公开路由
app.post('/login', async (c) => {
  // 这里应该有用户验证逻辑
  const userId = 123
  const username = 'example_user'

  // 创建 JWT 令牌
  const token = await jwt.sign({ userId, username }, JWT_SECRET)

  return c.json({ token })
})

// 使用 JWT 中间件保护路由
app.use('/api/*', jwt({ secret: JWT_SECRET }))

// 受保护的路由
app.get('/api/profile', async (c) => {
  // 获取已验证的 JWT 载荷
  const payload = c.get('jwtPayload')

  return c.json({
    userId: payload.userId,
    username: payload.username,
  })
})

app.listen(3000)

高级配置

typescript
import { Hono } from 'hono'
import { jwt } from '@hono/jwt'

const app = new Hono()

// JWT 配置
const jwtMiddleware = jwt({
  secret: 'your-secret-key',
  cookie: 'auth_token', // 从 cookie 中获取令牌
  alg: 'HS256', // 签名算法
  exp: '24h', // 令牌过期时间
})

// 自定义令牌提取
const customJwtMiddleware = jwt({
  secret: 'your-secret-key',
  getToken: (c) => {
    // 从自定义头部获取令牌
    const authHeader = c.req.header('X-Custom-Auth')
    if (!authHeader) return null
    return authHeader.replace('Bearer ', '')
  },
})

// 使用中间件
app.use('/api/*', jwtMiddleware)
app.use('/custom/*', customJwtMiddleware)

// 生成令牌的路由
app.post('/login', async (c) => {
  const { username } = await c.req.json()

  // 创建带有自定义过期时间的令牌
  const token = await jwt.sign(
    { username, role: 'user' },
    'your-secret-key',
    { expiresIn: '1h' }, // 1小时后过期
  )

  // 设置 cookie
  c.cookie('auth_token', token, {
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production',
    sameSite: 'strict',
    maxAge: 60 * 60, // 1小时
  })

  return c.json({ success: true })
})

// 错误处理
app.onError((err, c) => {
  if (err.message === 'JWT verification failed') {
    return c.json({ error: '认证失败' }, 401)
  }
  if (err.message === 'JWT expired') {
    return c.json({ error: '令牌已过期' }, 401)
  }

  console.error(err)
  return c.json({ error: '服务器错误' }, 500)
})

注意事项

  1. 始终使用强密钥并保持其安全,避免硬编码在代码中
  2. 在生产环境中,考虑使用环境变量存储密钥
  3. 设置合理的令牌过期时间,平衡安全性和用户体验
  4. 对于敏感操作,可以考虑使用刷新令牌机制
  5. 在 HTTPS 环境中使用 JWT,避免令牌被中间人攻击截获
  6. 不要在 JWT 中存储敏感信息,因为 JWT 的载荷部分可以被解码(虽然不能被篡改)

要保持清醒 永远不抱有意外的幻想 凭空的期待最要命