4.7 KiB
4.7 KiB
认证模块(auth)
证据来源:[SRC-FEAT-01] [SRC-API-01] [SRC-CODE-01:module/auth/]
1. 模块定位
- 模块目标:负责用户身份验证(企业微信OAuth + 账号密码备选)和 JWT Token 的签发、校验,为所有其他模块提供鉴权基础。
- 解决问题:500人规模的企业内部系统,需要统一身份验证入口,并将身份与角色绑定,为下游数据隔离提供
userId + role + departmentId上下文。
2. 功能清单
[SRC-API-01:四、API 接口设计 / SRC-CODE-01:module/auth/]
| 功能名称 | 功能描述 | 输入 | 输出 | 依赖模块 |
|---|---|---|---|---|
| 企业微信 OAuth 登录 | 通过企业微信授权 code 换取用户身份,查找系统用户,签发 JWT | wx_code | JWT Token + 用户信息(LoginResponse) | system(查sys_user) |
| 账号密码登录(备选) | 用用户名+密码登录,BCrypt 验证密码 | username, password | JWT Token + 用户信息 | system(查sys_user) |
| 获取当前用户信息 | 解析 Token 返回用户基本信息 | Authorization Header | UserInfoResponse | - |
| 微信小程序登录(预留) | 通过小程序 code 获取用户信息 | WechatLoginRequest | JWT Token | system |
| Token 携带与拦截 | AuthInterceptor 拦截所有受保护请求,提取 Token 注入 UserContext | Authorization: Bearer {token} | UserContext(ThreadLocal) | - |
3. 核心逻辑
3.1 业务规则
- 企业微信登录路径:前端传 code → 后端调 weixin-java-cp SDK 换
access_token→ 获取wx_userid→ 查sys_user.wx_userid匹配 → 用户不存在则返回错误(不自动注册)[SRC-FEAT-01] - JWT Payload 包含:userId、role、departmentId,有效期由配置决定
- 密码存储:BCrypt 加密(Spring Security 6.x),初始管理员密码
admin123已预置 [SRC-SQL-01:5.4]
3.2 校验逻辑
| 校验项 | 规则 | 失败响应 |
|---|---|---|
| wx_userid 是否存在于 sys_user | 必须已由管理员录入 | 返回错误:用户未录入,请联系管理员 |
| sys_user.status | 必须为 0(启用) | 返回错误:账号已禁用 |
| Token 有效性 | 未过期、签名正确 | 返回 401 |
| 受保护接口 Token 缺失 | 无 Authorization Header | 返回 401 |
3.3 状态流转
stateDiagram-v2
[*] --> 未认证
未认证 --> 已认证 : 登录成功(JWT签发)
已认证 --> 未认证 : Token过期 / 主动登出
已认证 --> 已认证 : Token续期(如有配置)
4. 数据结构
4.1 涉及数据表
sys_user(读取,不由本模块创建)[SRC-SQL-01]
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT | 用户主键 |
| wx_userid | VARCHAR(100) | 企业微信用户ID(唯一索引 uk_wx_userid) |
| username | VARCHAR(50) | 账号密码登录用账号(唯一索引 uk_username) |
| password | VARCHAR(100) | BCrypt加密密码 |
| role | TINYINT | 0-管理员 / 1-讲师 / 2-学员 |
| department_id | BIGINT | 所属部门ID(会注入 JWT Payload) |
| status | TINYINT | 0-启用 / 1-禁用 |
4.2 DTO/VO 定义
[SRC-CODE-01:module/auth/dto/]
| 类名 | 方向 | 关键字段 |
|---|---|---|
| LoginRequest | 入参 | username, password |
| WechatLoginRequest | 入参 | code(企业微信授权码) |
| LoginResponse | 出参 | token, userId, realName, role, departmentId |
| UserInfoResponse | 出参 | 同 LoginResponse(从 Token 解析) |
5. 对外接口
[SRC-API-01]
| API 名称 | 方法 | 路径 | 权限 |
|---|---|---|---|
| 企业微信登录 | POST | /api/auth/wechat/login | 公开 |
| 账号密码登录 | POST | /api/auth/login | 公开 |
| 获取当前用户 | GET | /api/auth/me | 需 Token |
事件机制:登录成功后,UserContext(ThreadLocal)持有用户信息,供同请求链路的所有 Service 使用,请求结束后清除。[SRC-CODE-01:common/context/UserContextHolder.java]
6. 异常与边界处理
| 场景 | 处理方式 |
|---|---|
| 企业微信 API 调用超时/失败 | 返回 503,提示"企业微信服务暂时不可用,请稍后重试" |
| 企业微信 code 已使用(重放) | 企业微信 SDK 返回错误,转化为 400 |
| 用户 wx_userid 存在但账号被禁用(status=1) | 返回 403,提示"账号已禁用,请联系管理员" |
| sys_user 中无对应 wx_userid | 返回 403,提示"用户未录入系统,请联系管理员" |
| Token 格式错误(非JWT) | AuthInterceptor 捕获,返回 401 |
| Token 过期 | AuthInterceptor 捕获,返回 401,前端跳转登录页 |
| 并发登录(同一账号多端) | 当前设计无限制,多端独立 Token 有效 |