账户与认证
API 事实来源:Django 后端自动文档
模块职责
accounts 负责身份、角色、登录方式和请求期角色上下文。业务模块通过它获得登录态和 current_role,而不是各自解释认证细节。
代码入口:
backend/apps/accounts/models/backend/apps/accounts/views/backend/apps/accounts/serializers/backend/apps/accounts/authentication.pybackend/apps/accounts/middleware.pybackend/apps/accounts/tasks.py
为什么当前角色不落库
用户可以同时拥有多个角色,roles 表示可用身份集合,current_role 表示本次请求选择的身份。把当前角色做成请求上下文可以避免“用户切换身份后污染全局状态”,也让同一账号在不同客户端中保持独立。
current_role 来自 JWT 声明或 X-Current-Role,由中间件校验是否属于 user.roles。角色标识符因此是跨模块协议,改名会影响所有业务模块中的字符串判断。
auth_version 用于撤销旧 token。密码、角色或状态变化后,需要走现有版本递增路径,否则旧 token 会继续有效。
Web 端通过 cookie 承载 JWT,小程序端通过响应体交付 token。SM2 解密失败后的明文回退是兼容旧客户端的路径,不是新的认证设计目标。
修改认证时看什么
- 权限判断优先复用现有 role helper 和 permission 模式。直接读取
user.roles[0]会绕过当前活跃角色。 - 新登录方式需要同时定义 token 交付方式、TOTP 处理、
auth_version校验和 locale 初始化。 - 用户批量导入是异步任务。Excel 解析和用户创建放回请求线程会重新引入超时风险。
容易漏掉的流程
- 外教注册是匿名入口。改动后检查默认角色、账号状态和注册后的登录行为。
- 微信登录依赖
wxid=open_id绑定。绑定逻辑影响小程序登录、绑定和解绑接口。 - WebAuthn、TOTP 和 SM2 都涉及客户端协作,单元测试之外还需要真实前端流程验证。