# 鉴权接口实战

URL: https://caijiao.org/hono/06-practice/03-auth-api
Source: docs/hono/06-practice/03-auth-api.md
Description: 使用 Hono 编写登录、JWT 签发、鉴权中间件和当前用户接口，理解 API 鉴权的基础流程。

这一节实现一个最小 JWT 鉴权流程：登录、签发 Token、保护接口、读取当前用户。

## 示例用户

```ts
type User = {
  id: string
  email: string
  password: string
  role: 'admin' | 'user'
}

const users: User[] = [
  {
    id: 'u_1',
    email: 'admin@example.com',
    password: 'secret',
    role: 'admin',
  },
]
```

示例为了简洁使用明文密码。真实项目必须使用 Argon2、bcrypt 或其他安全哈希方案。

## 登录接口

```ts
import { sign } from 'hono/jwt'

const jwtSecret = 'change-me'

app.post('/auth/login', async (c) => {
  const body = await c.req.json<{
    email?: string
    password?: string
  }>()

  const user = users.find((item) => item.email === body.email)

  if (!user || user.password !== body.password) {
    return c.json({ message: 'Invalid email or password' }, 401)
  }

  const token = await sign(
    {
      sub: user.id,
      role: user.role,
      exp: Math.floor(Date.now() / 1000) + 60 * 60,
    },
    jwtSecret,
  )

  return c.json({ token })
})
```

## 保护路由

```ts
import { jwt } from 'hono/jwt'

app.use(
  '/auth/me',
  jwt({
    secret: jwtSecret,
  }),
)

app.get('/auth/me', (c) => {
  const payload = c.get('jwtPayload')
  const user = users.find((item) => item.id === payload.sub)

  if (!user) {
    return c.json({ message: 'User not found' }, 404)
  }

  return c.json({
    id: user.id,
    email: user.email,
    role: user.role,
  })
})
```

## 调用流程

登录：

```bash
curl -X POST http://localhost:3000/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"admin@example.com","password":"secret"}'
```

访问当前用户：

```bash
curl http://localhost:3000/auth/me \
  -H "Authorization: Bearer <token>"
```

## 生产改进

- 使用密码哈希，不保存明文密码。
- 使用 HTTPS，避免 Token 在传输中泄露。
- Token 密钥通过环境变量或 Secret 管理。
- 设计刷新 Token、退出登录和吊销机制。
- 对登录接口加限流和审计日志。
- 不要在 Token 中放敏感资料。

JWT 适合无状态 API，但无状态不等于无需管理。权限变更、账号禁用、风险登录等场景仍然需要服务端策略。
