- 新增文档模板和导航结构 - 实现服务器基础API路由和控制器 - 添加扩展插件配置和前端框架 - 引入多租户和权限管理模块 - 集成日志和数据库配置 - 添加核心业务模型和类型定义
8.9 KiB
8.9 KiB
AuthService 文档
概述
AuthService 是一个功能强大的认证服务,支持 JWT、OAuth2.0 和多因子认证(MFA),为 Crawlful Hub 项目提供统一的身份认证和授权管理。
核心功能
1. JWT 认证
- 生成和验证 JWT 令牌
- 支持令牌刷新
- 携带 4-tuple TraceContext(tenantId, 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 认证
// 登录
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 认证
// 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();
多因子认证
// 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();
安全注意事项
- 密码安全:使用 bcrypt 对密码进行哈希处理,避免明文存储
- 令牌安全:JWT 令牌和 OAuth2.0 令牌都有过期时间,避免长期使用
- 密钥管理:JWT 密钥和 MFA 密钥应该妥善保管,避免泄露
- 权限控制:基于角色的访问控制(RBAC),确保用户只能访问授权的资源
- 输入验证:所有用户输入都应该进行验证,避免注入攻击
- HTTPS:在生产环境中使用 HTTPS,避免数据传输过程中的窃听
部署配置
环境变量
JWT_SECRET:JWT 签名密钥,生产环境中应该使用强随机字符串JWT_EXPIRES_IN:JWT 令牌过期时间,默认 24hREFRESH_TOKEN_EXPIRES_IN:刷新令牌过期时间,默认 7dOAUTH2_ACCESS_TOKEN_EXPIRES_IN:OAuth2.0 访问令牌过期时间,默认 1hOAUTH2_AUTH_CODE_EXPIRES_IN:OAuth2.0 授权码过期时间,默认 10m
数据库配置
- 使用 MySQL 8.0
- 所有表都以
cf_为前缀 - 建立适当的索引,提高查询性能
- 使用外键约束,确保数据完整性
故障排查
常见问题
- 令牌过期:如果收到 401 Unauthorized 错误,检查令牌是否过期,使用刷新令牌获取新令牌
- 密码错误:如果登录失败,检查用户名和密码是否正确
- MFA 验证失败:检查 TOTP 码是否正确,确保时间同步
- OAuth2.0 授权失败:检查客户端 ID、密钥和重定向 URI 是否正确
日志
AuthService 会记录所有认证相关的操作和错误,日志文件位于 logs/ 目录下,可以通过查看日志来排查问题。
总结
AuthService 是一个功能完整、安全可靠的认证服务,支持多种认证方式,为 Crawlful Hub 项目提供统一的身份认证和授权管理。通过合理使用 AuthService,可以确保系统的安全性和可靠性,同时为用户提供良好的认证体验。