116 lines
3.1 KiB
Markdown
116 lines
3.1 KiB
Markdown
# 认证模块
|
||
|
||
## 技术栈
|
||
- 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>
|
||
```
|