Files
zhuiguang-ai/.trae/specs/modules/06-auth.md
T

116 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 认证模块
## 技术栈
- NextAuth.js v4
- Credentials Provider(用户邮箱密码)
- GitHub OAuth Provider
- JWT Session策略
- bcrypt 密码加密
## 配置 (`src/lib/auth.ts`)
### 用户认证
- 邮箱+密码注册/登录
- 用户数据存储在User表
- 密码bcrypt加密
- GitHub OAuth登录(自动创建/关联用户)
- **OAuth 竞态处理**: GitHub OAuth 并发创建用户时 P2002 唯一约束冲突自动回退 findFirst
- 登录频率限制: 7次/分钟
### 登录流程
1. 用户输入邮箱+密码
2. 检查登录频率限制
3. 查询User表获取用户
4. bcrypt.compare验证密码
5. 返回用户信息(id, email, name, role)
6. JWT回调将用户信息加入token
7. Session回调将token信息传递给session
### GitHub OAuth流程
1. 用户点击GitHub登录
2. 重定向到GitHub授权
3. 回调获取profile信息
4. 检查oauthProvider+oauthId是否已存在
5. 不存在则创建新用户
6. 返回用户信息
### Session策略
- 使用JWT,不使用数据库session
- JWT密钥: `NEXTAUTH_SECRET` 环境变量
- Session有效期: 30天
- Token包含: id, role
### 回调函数
- `signIn`: GitHub OAuth自动创建用户
- `jwt`: 登录时将用户信息加入token
- `session`: 将token中的用户信息传递给session
## 路由保护 (`src/middleware.ts`)
### 保护规则
- 保护 `/admin` 下所有路由
- 保护 `/api/admin/:path*` 路由
- 保护 `/api/user/:path*` 路由
- 跳过 `/admin/login`
- 使用NextAuth middleware进行认证检查
### 权限检查
- 检查token是否存在
- 检查role是否为admin或vip
- 未登录重定向到 /admin/login
- 无权限返回401/403
## 管理员API认证 (`src/lib/admin-auth.ts`)
### getAdminSession
- 获取当前会话
- 验证用户角色
- 支持role字符串和roleId双重验证
- 缓存机制(React cache)
### requireAdmin中间件
- 所有 `/api/admin/` 路由必须使用requireAdmin中间件
- 验证流程: 检查session → 验证角色
- 返回401/403错误响应
### getUserPermissionKeys
- 获取用户权限键集合
- 基于roleId关联Role表查询
- 缓存机制
### requirePermission
- 细粒度权限点校验
- 检查permissionKeys是否包含指定key
- 返回403如果缺少权限
### getAllUserPermissions
- 获取当前用户全部权限集合
- 支持admin角色(返回全部权限)
- 支持roleId关联角色
## 前端权限Hook (`src/lib/use-permission.ts`)
### usePermission
- 客户端Hook
- 获取当前用户权限
- 缓存机制
- 提供方法:
- `can(key)` — 检查单个权限
- `canAny(keys)` — 检查任一权限
- `canAll(keys)` — 检查全部权限
- `refresh` — 刷新权限
## 登录页
- 管理员登录: `src/app/(admin)/admin/login/page.tsx` (原生HTML表单 + CSRF Token)
- 用户登录: `src/app/login/page.tsx` (NextAuth Credentials + GitHub OAuth)
- 用户登录弹窗: `src/components/common/LoginModal.tsx`
- 登录表单: `src/components/common/LoginForm.tsx`
## 环境变量
```
NEXTAUTH_URL=http://localhost:8301
NEXTAUTH_SECRET=zhuiguang-ai-dev-secret
GITHUB_CLIENT_ID=<github-oauth-client-id>
GITHUB_CLIENT_SECRET=<github-oauth-secret>
```