Files
makemd/server/docs/auth-service.md
wurenzhi 136c2fa579 feat: 初始化项目结构并添加核心功能模块
- 新增文档模板和导航结构
- 实现服务器基础API路由和控制器
- 添加扩展插件配置和前端框架
- 引入多租户和权限管理模块
- 集成日志和数据库配置
- 添加核心业务模型和类型定义
2026-03-17 22:07:19 +08:00

349 lines
8.9 KiB
Markdown
Raw Permalink 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.
# AuthService 文档
## 概述
AuthService 是一个功能强大的认证服务,支持 JWT、OAuth2.0 和多因子认证MFA为 Crawlful Hub 项目提供统一的身份认证和授权管理。
## 核心功能
### 1. JWT 认证
- 生成和验证 JWT 令牌
- 支持令牌刷新
- 携带 4-tuple TraceContexttenantId, shopId, taskId, traceId
### 2. OAuth2.0 认证
- 客户端管理
- 授权码流程
- 访问令牌生成和刷新
- 支持多种授权类型
### 3. 多因子认证MFA
- 基于时间的一次性密码TOTP
- 支持 SMS 和 EMAIL 验证(预留接口)
## 数据库表结构
### cf_user
- id: 用户ID
- username: 用户名
- password_hash: 密码哈希
- role: 角色
- tenant_id: 租户ID
- shop_id: 店铺ID可选
- status: 状态ACTIVE/DISABLED
- created_at: 创建时间
- updated_at: 更新时间
### cf_oauth_client
- id: 客户端ID
- client_id: 客户端标识符
- client_secret: 客户端密钥哈希
- redirect_uri: 重定向URI
- grant_types: 授权类型
- scope: 权限范围
- tenant_id: 租户ID
- created_at: 创建时间
- updated_at: 更新时间
### cf_oauth_code
- id: 授权码ID
- code: 授权码
- client_id: 客户端ID
- user_id: 用户ID
- redirect_uri: 重定向URI
- scope: 权限范围
- expires_at: 过期时间
- created_at: 创建时间
- updated_at: 更新时间
### cf_oauth_token
- id: 令牌ID
- access_token: 访问令牌
- refresh_token: 刷新令牌
- client_id: 客户端ID
- user_id: 用户ID
- scope: 权限范围
- expires_at: 过期时间
- created_at: 创建时间
- updated_at: 更新时间
### cf_user_mfa
- id: MFA记录ID
- user_id: 用户ID
- method: 认证方法TOTP/SMS/EMAIL
- secret: 密钥
- enabled: 是否启用
- created_at: 创建时间
- updated_at: 更新时间
### cf_refresh_token
- id: 刷新令牌ID
- user_id: 用户ID
- token: 刷新令牌
- expires_at: 过期时间
- created_at: 创建时间
- updated_at: 更新时间
## API 接口
### 公开接口
#### POST /api/auth/login
- 功能:用户登录
- 请求参数:
- username: 用户名
- password: 密码
- 响应:
- token: JWT令牌
- refreshToken: 刷新令牌
- user: 用户信息
#### POST /api/auth/refresh
- 功能:刷新令牌
- 请求参数:
- refreshToken: 刷新令牌
- 响应:
- token: 新的JWT令牌
- user: 用户信息
#### POST /api/auth/register
- 功能:注册新用户
- 请求参数:
- username: 用户名
- password: 密码
- role: 角色
- tenantId: 租户ID
- shopId: 店铺ID可选
- 响应:
- user: 用户信息
#### POST /api/auth/oauth2/token
- 功能获取OAuth2.0访问令牌
- 请求参数:
- grant_type: 授权类型authorization_code/refresh_token
- code: 授权码当grant_type为authorization_code时
- refresh_token: 刷新令牌当grant_type为refresh_token时
- client_id: 客户端ID
- client_secret: 客户端密钥
- redirect_uri: 重定向URI
- 响应:
- access_token: 访问令牌
- refresh_token: 刷新令牌
- expires_in: 过期时间(秒)
- scope: 权限范围
### 需要认证的接口
#### GET /api/auth/me
- 功能:获取当前用户信息
- 响应:
- user: 用户信息
#### POST /api/auth/mfa/enable
- 功能:启用多因子认证
- 请求参数:
- method: 认证方法TOTP/SMS/EMAIL
- secret: 密钥
- 响应:
- success: 是否成功
#### POST /api/auth/mfa/verify
- 功能:验证多因子认证码
- 请求参数:
- method: 认证方法TOTP/SMS/EMAIL
- code: 验证码
- 响应:
- success: 是否成功
#### GET /api/auth/oauth2/authorize
- 功能OAuth2.0授权
- 请求参数:
- client_id: 客户端ID
- redirect_uri: 重定向URI
- scope: 权限范围
- state: 状态参数
- 响应:
- 重定向到redirect_uri携带code和state参数
#### POST /api/auth/oauth2/client
- 功能创建OAuth2.0客户端
- 请求参数:
- clientId: 客户端ID
- clientSecret: 客户端密钥
- redirectUri: 重定向URI
- grantTypes: 授权类型
- scope: 权限范围
- 响应:
- success: 是否成功
## 使用示例
### JWT 认证
```typescript
// 登录
const loginResponse = await fetch('/api/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: 'admin',
password: 'admin123'
})
});
const { token, refreshToken, user } = await loginResponse.json();
// 使用令牌访问受保护的接口
const protectedResponse = await fetch('/api/auth/me', {
headers: {
'Authorization': `Bearer ${token}`
}
});
// 刷新令牌
const refreshResponse = await fetch('/api/auth/refresh', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
refreshToken
})
});
const { token: newToken } = await refreshResponse.json();
```
### OAuth2.0 认证
```typescript
// 1. 重定向用户到授权页面
const authorizationUrl = `/api/auth/oauth2/authorize?client_id=client1&redirect_uri=http://localhost:3000/callback&scope=read%20write&state=12345`;
window.location.href = authorizationUrl;
// 2. 处理回调在redirect_uri指定的页面
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');
const state = urlParams.get('state');
// 3. 使用授权码获取访问令牌
const tokenResponse = await fetch('/api/auth/oauth2/token', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
grant_type: 'authorization_code',
code,
client_id: 'client1',
client_secret: 'secret1',
redirect_uri: 'http://localhost:3000/callback'
})
});
const { access_token, refresh_token, expires_in, scope } = await tokenResponse.json();
// 4. 使用访问令牌访问受保护的接口
const protectedResponse = await fetch('/api/protected', {
headers: {
'Authorization': `Bearer ${access_token}`
}
});
// 5. 使用刷新令牌获取新的访问令牌
const refreshResponse = await fetch('/api/auth/oauth2/token', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
grant_type: 'refresh_token',
refresh_token,
client_id: 'client1',
client_secret: 'secret1'
})
});
const { access_token: newAccessToken } = await refreshResponse.json();
```
### 多因子认证
```typescript
// 1. 生成TOTP密钥
const { secret, otpauthUrl } = AuthService.generateTOTPSecret();
// 2. 启用MFA
const enableResponse = await fetch('/api/auth/mfa/enable', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
method: 'TOTP',
secret
})
});
// 3. 验证MFA码
const verifyResponse = await fetch('/api/auth/mfa/verify', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
method: 'TOTP',
code: '123456' // 从认证器应用获取
})
});
const { success } = await verifyResponse.json();
```
## 安全注意事项
1. **密码安全**:使用 bcrypt 对密码进行哈希处理,避免明文存储
2. **令牌安全**JWT 令牌和 OAuth2.0 令牌都有过期时间,避免长期使用
3. **密钥管理**JWT 密钥和 MFA 密钥应该妥善保管,避免泄露
4. **权限控制**基于角色的访问控制RBAC确保用户只能访问授权的资源
5. **输入验证**:所有用户输入都应该进行验证,避免注入攻击
6. **HTTPS**:在生产环境中使用 HTTPS避免数据传输过程中的窃听
## 部署配置
### 环境变量
- `JWT_SECRET`JWT 签名密钥,生产环境中应该使用强随机字符串
- `JWT_EXPIRES_IN`JWT 令牌过期时间,默认 24h
- `REFRESH_TOKEN_EXPIRES_IN`:刷新令牌过期时间,默认 7d
- `OAUTH2_ACCESS_TOKEN_EXPIRES_IN`OAuth2.0 访问令牌过期时间,默认 1h
- `OAUTH2_AUTH_CODE_EXPIRES_IN`OAuth2.0 授权码过期时间,默认 10m
### 数据库配置
- 使用 MySQL 8.0
- 所有表都以 `cf_` 为前缀
- 建立适当的索引,提高查询性能
- 使用外键约束,确保数据完整性
## 故障排查
### 常见问题
1. **令牌过期**:如果收到 401 Unauthorized 错误,检查令牌是否过期,使用刷新令牌获取新令牌
2. **密码错误**:如果登录失败,检查用户名和密码是否正确
3. **MFA 验证失败**:检查 TOTP 码是否正确,确保时间同步
4. **OAuth2.0 授权失败**:检查客户端 ID、密钥和重定向 URI 是否正确
### 日志
AuthService 会记录所有认证相关的操作和错误,日志文件位于 `logs/` 目录下,可以通过查看日志来排查问题。
## 总结
AuthService 是一个功能完整、安全可靠的认证服务,支持多种认证方式,为 Crawlful Hub 项目提供统一的身份认证和授权管理。通过合理使用 AuthService可以确保系统的安全性和可靠性同时为用户提供良好的认证体验。