简介
本文件面向移动端与Web前端开发者,提供用户认证模块的完整API文档。覆盖注册、登录(账号密码/手机验证码)、登出、登录态检查、忘记密码等核心流程;详细说明密码加密、会话管理、Token机制、自动登录与“记住我”能力;给出成功、失败、过期等典型场景的请求与响应示例;并总结安全实践建议。
项目结构
认证相关代码主要分布在以下位置:
- API端控制器:处理小程序/移动端的HTTP请求与响应
- 认证门面与中间件:解析Authorization头中的Bearer Token,注入当前用户上下文
- Token服务:签发、校验、吊销不透明随机Token
- 后台管理员认证:基于Session与Remember-Me Cookie的有状态登录
- 小程序客户端:本地存储Token并在后续请求中携带
graph TB
Client["客户端<br/>小程序/Web"] --> API["API 控制器<br/>UserController"]
API --> Guard["API 认证门面<br/>Auth"]
Guard --> TokenSvc["Token 服务<br/>ApiTokenService"]
API --> LoginSvc["登录校验服务<br/>LoginService"]
API --> UserSvc["用户服务<br/>UserService"]
Admin["后台管理员"] --> AdminGuard["后台认证<br/>AuthService"]
核心组件
- API 认证门面(Auth):实现无状态鉴权,负责从Token解析用户上下文、检查登录态、构建轻量用户资料与工作端信息。
- Token 服务(ApiTokenService):签发带过期时间的不透明随机Token,仅存哈希值;支持按设备吊销与全局吊销。
- 登录校验服务(LoginService):统一校验账号密码或手机验证码,返回用户行或错误;IP限流、历史密码升级由该层完成。
- 后台管理员认证(AuthService):基于Session与Remember-Me Cookie的有状态登录,支持IP限流、锁定、自动续登。
- 认证管理器(AuthManager):多Guard注册与解析入口,强制显式指定guard名称(admin/front/api)。
架构总览
API端采用无状态Token鉴权:客户端在登录后保存Token,并在后续请求通过Authorization: Bearer <token>传递;中间件或控制器调用Auth门面解析Token,得到用户ID与资料,再交由业务控制器处理。后台管理员使用Session+Remember-Me的有状态模式,具备自动续登能力。
sequenceDiagram
participant C as "客户端"
participant U as "UserController"
participant L as "LoginService"
participant A as "Auth(门面)"
participant T as "ApiTokenService"
participant DB as "数据库"
C->>U : POST /user/login_post (username/password)
U->>L : validateLoginCredentials(...)
L-->>U : {ok,user,errors,field}
U->>A : auth('api') -> checkLoginState(token)
A->>T : resolve(token)
T->>DB : 查询 token_hash
DB-->>T : 命中/未命中
T-->>A : userId 或 0
A-->>U : 登录态检查结果
U-->>C : 返回 user + dou.auth
详细接口说明
以下为API端用户认证相关接口的规范说明。所有接口均返回统一JSON结构,成功时包含data字段,失败时包含错误码与消息。
注册
- 方法:POST
- URL:/user/register
- 说明:获取注册表单所需配置与验证码Token对(邮箱/短信),用于前端渲染与下发验证码。
- 请求参数:无必填(可选promotion_user_sn用于推广关系)
- 响应字段:
- captcha_token:验证码令牌
- storage_captcha_token:存储用验证码令牌
- promotion_user_sn:推广用户编号
- sns_token:第三方登录令牌
- login_mode:登录模式(email/mobile)
- mail_username:是否启用邮箱用户名
- sms_accessKeyId:是否启用短信服务
提交注册
- 方法:POST
- URL:/user/register_post
- 说明:创建新用户,校验邮箱/手机号唯一性、密码强度与确认、验证码有效性;成功后立即登录并返回用户信息与认证标志。
- 请求参数:
- email 或 mobile:二选一,需唯一
- password:满足密码规则,且需confirmed字段一致
- verification_data:验证码数据(含code/account/ontime)
- promotion_user_sn:推广关系
- sns:第三方绑定信息(可选)
- 响应字段:
- user:登录后的用户信息(含Token)
- dou.auth.is_work:是否工作端身份
账号密码登录
- 方法:POST
- URL:/user/login_post
- 说明:校验账号密码,支持IP限流与历史密码升级;成功后返回用户信息与认证标志。
- 请求参数:
- username:邮箱或手机号
- password:明文密码
- 响应字段:
- user:登录后的用户信息(含Token)
- dou.auth.is_work:是否工作端身份
手机验证码登录
- 方法:POST
- URL:/user/login_phone_post
- 说明:使用手机号+验证码登录;校验验证码有效期与内容;成功后返回用户信息与认证标志。
- 请求参数:
- mobile:手机号
- verification:验证码
- verification_data:验证码数据(含code/account/ontime)
- promotion_user_sn:推广关系
- 响应字段:
- user:登录后的用户信息(含Token)
- dou.auth.is_work:是否工作端身份
忘记密码(发送重置邮件)
- 方法:POST
- URL:/user/password_reset_post
- 说明:根据邮箱生成重置令牌并发送邮件;若邮箱不存在返回404。
- 请求参数:
- email:用户邮箱
- 响应:
- 成功:提示已发送
- 失败:404(邮箱不存在)或500(邮件发送失败)
修改密码
- 方法:POST
- URL:/user/password_post
- 说明:验证旧密码与新密码一致性;成功后返回relogin=true,要求客户端重新登录。
- 请求参数:
- old_password:旧密码
- password:新密码(需confirmed一致)
- 响应字段:
- relogin:true表示需要重新登录
登出
- 方法:POST
- URL:/user/logout
- 说明:吊销当前设备的API会话Token。
- 请求头:
- Authorization: Bearer <token>
- 响应:空数据
登录态检查
- 方法:GET/POST
- URL:/user/check_login_state
- 说明:校验当前Token是否有效,返回登录状态、用户ID及手机号绑定情况。
- 请求头:
- Authorization: Bearer <token>
- 响应字段:
- msg:ok/fail
- reason:missing_credential/invalid_credential(失败原因)
- user_id:用户ID
- phone:yes/no(是否绑定手机号)
- login_phone:是否需要手机号登录(布尔)
会员中心首页(聚合认证状态)
- 方法:GET
- URL:/user
- 说明:返回用户基础资料与认证状态聚合(is_login/is_vip/is_work/is_distribution),以及VIP/工作端/分销详情。
- 请求头:
- Authorization: Bearer <token>
- 响应字段:
- title/welcome/link_user_center/if_connect_plugin
- dou.user:用户资料
- dou.auth:认证标志
- dou.vip/dou.work/dou.distribution:扩展身份详情
依赖关系分析
- UserController依赖LoginService进行凭据校验,依赖UserAuthService签发Token,依赖UserService判断工作端身份。
- Auth门面依赖ApiTokenService解析Token,并通过DB读取用户资料。
- ApiTokenService负责Token生命周期管理,持久化到user_token表,仅存哈希值。
- 后台AuthService实现有状态登录,结合Session与Remember-Me Cookie,支持IP限流与锁定。
classDiagram
class UserController {
+register()
+registerPost()
+loginPost()
+loginPhonePost()
+passwordResetPost()
+passwordPost()
+logout()
+checkLoginState()
+index()
}
class LoginService {
+validateLoginCredentials()
}
class Auth {
+checkLoginState(token)
+resolveUserContext(token)
+hydrate(context)
}
class ApiTokenService {
+issue(userId, ip)
+resolve(token)
+revoke(token)
+revokeAllForUser(userId)
}
class AuthService {
+attempt(credentials, remember, ip)
+login(user, remember, ip)
+logout()
+restoreFromSession(ip)
}
UserController --> LoginService : "校验凭据"
UserController --> Auth : "鉴权门面"
Auth --> ApiTokenService : "解析Token"
UserController --> AuthService : "后台登录(对比)"
性能与安全考虑
- 密码安全:
- 登录校验支持历史md5散列即时升级为bcrypt,提升安全性。
- 修改密码需验证旧密码,成功后要求重新登录。
- 防暴力破解:
- IP限流:登录失败达到阈值后限制一段时间内再次尝试。
- 账号锁定:多次失败后锁定账户一定时间。
- Token安全:
- Token为64字符十六进制随机串,服务端仅存sha256(token),泄库不可逆推。
- Token带过期时间(默认30天),支持按设备吊销与全局吊销。
- 解析侧使用hash_equals恒定时间比较,防止时序攻击。
- 会话安全:
- 后台管理员登录使用Session+Remember-Me Cookie,支持自动续登与CSRF保护。
- 登出时清理Session与Cookie,确保彻底退出。
- 传输安全:
- 建议使用HTTPS传输,避免Token泄露。
- 敏感操作(如改密)需重新登录,降低风险面。
故障排查指南
- 登录失败:
- 检查IP是否被限流,查看错误提示是否为“登录IP被锁定”。
- 确认账号是否存在、密码是否正确,注意历史md5散列升级逻辑。
- Token无效:
- 检查Authorization头格式是否正确(Bearer <token>)。
- 确认Token是否过期或被吊销(登出/改密会吊销)。
- 会话过期:
- 后台管理员登录态基于Session,超时将清空;Remember-Me可自动续登。
- API端Token过期后需重新登录。
- 邮件发送失败:
- 忘记密码接口返回500时检查邮件服务配置。
结论
本项目用户认证模块采用前后端分离设计:API端使用无状态Token鉴权,后台管理员使用有状态Session+Remember-Me。通过严格的密码策略、IP限流、账号锁定、Token哈希存储与过期机制,保障认证安全。开发者应遵循接口规范,正确传递Token,处理成功与失败场景,确保安全集成。
附录:集成要点与示例
- 客户端存储Token:
- 登录后将Token存入本地存储(如小程序storage),并在后续请求中通过Authorization: Bearer <token>传递。
- 登录态恢复:
- 应用启动时调用会员中心首页接口,获取认证状态聚合(is_login等),用于UI展示与路由守卫。
- 典型场景示例:
- 成功登录:返回user与dou.auth,客户端保存Token并跳转主页。
- 失败认证:返回错误码与消息,提示用户重试或检查凭据。
- 会话过期:返回401未授权,引导用户重新登录。