Files
makemd/server/docs/auth-service.md

349 lines
8.9 KiB
Markdown
Raw Normal View History

# 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可以确保系统的安全性和可靠性同时为用户提供良好的认证体验。