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

8.9 KiB
Raw Blame 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 认证

// 登录
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();

安全注意事项

  1. 密码安全:使用 bcrypt 对密码进行哈希处理,避免明文存储
  2. 令牌安全JWT 令牌和 OAuth2.0 令牌都有过期时间,避免长期使用
  3. 密钥管理JWT 密钥和 MFA 密钥应该妥善保管,避免泄露
  4. 权限控制基于角色的访问控制RBAC确保用户只能访问授权的资源
  5. 输入验证:所有用户输入都应该进行验证,避免注入攻击
  6. HTTPS:在生产环境中使用 HTTPS避免数据传输过程中的窃听

部署配置

环境变量

  • JWT_SECRETJWT 签名密钥,生产环境中应该使用强随机字符串
  • JWT_EXPIRES_INJWT 令牌过期时间,默认 24h
  • REFRESH_TOKEN_EXPIRES_IN:刷新令牌过期时间,默认 7d
  • OAUTH2_ACCESS_TOKEN_EXPIRES_INOAuth2.0 访问令牌过期时间,默认 1h
  • OAUTH2_AUTH_CODE_EXPIRES_INOAuth2.0 授权码过期时间,默认 10m

数据库配置

  • 使用 MySQL 8.0
  • 所有表都以 cf_ 为前缀
  • 建立适当的索引,提高查询性能
  • 使用外键约束,确保数据完整性

故障排查

常见问题

  1. 令牌过期:如果收到 401 Unauthorized 错误,检查令牌是否过期,使用刷新令牌获取新令牌
  2. 密码错误:如果登录失败,检查用户名和密码是否正确
  3. MFA 验证失败:检查 TOTP 码是否正确,确保时间同步
  4. OAuth2.0 授权失败:检查客户端 ID、密钥和重定向 URI 是否正确

日志

AuthService 会记录所有认证相关的操作和错误,日志文件位于 logs/ 目录下,可以通过查看日志来排查问题。

总结

AuthService 是一个功能完整、安全可靠的认证服务,支持多种认证方式,为 Crawlful Hub 项目提供统一的身份认证和授权管理。通过合理使用 AuthService可以确保系统的安全性和可靠性同时为用户提供良好的认证体验。