认证与用户账号 API

1. 登录

微信小程序登录

POST /api/v1/auth/login/wechat

Body

{
  "code": "小程序 wx.login() 返回的临时登录凭证",
  "totp_code": "123456"    // 当账号启用 TOTP 时必填
}

说明:

  • 后端通过 code 向微信服务器换取 openid,查找已绑定该 openid 的用户

  • 小程序不支持 Cookie,Token 直接在响应体中返回,小程序需自行存储

邮箱/学号/工号 + 密码登录

POST /api/v1/auth/login/email

Body

{
  "email": "teacher@school.edu",    // 支持邮箱或 user_code
  "password": "your_password",
  "totp_code": "123456"             // 当账号启用 TOTP 时必填
}

已启用 TOTP 的账号在使用微信登录时,同样需要在请求体中携带 totp_code 字段。

1.1 双因素认证(TOTP)

为账号启用基于时间的一次性密码:

POST /api/v1/auth/totp/setup

返回值示例:

{
  "code": 0,
  "message": "success",
  "data": {
    "secret": "BASE32SECRET",
    "provisioning_uri": "otpauth://totp/Classroom%20Manager:tester%40school.edu?..."
  }
}

完成扫描后提交验证码以启用:

POST /api/v1/auth/totp/enable

Body

{
  "totp_code": "123456"
}

1.2 无密码登录(WebAuthn)

本系统支持使用安全密钥 / 平台设备进行 WebAuthn 认证,流程分为「注册密钥」和「登录」两步。所有接口均遵循统一 success/error 返回结构。

注册安全密钥(需登录后操作)

  1. 请求注册参数(传递可选 device_name 便于备注设备):

POST /api/v1/auth/webauthn/options/register

返回值包含浏览器 navigator.credentials.create 所需的 publicKey 参数。

  1. 提交浏览器生成的凭证:

POST /api/v1/auth/webauthn/register

Body 示例:

{
  "credential": { ... },
  "device_name": "MacBook Touch ID"
}

使用安全密钥登录(匿名可访问)

  1. 请求登录参数:

POST /api/v1/auth/webauthn/options/login

Body

{ "identifier": "teacher@school.edu" }
  1. 提交认证结果以换取 JWT:

POST /api/v1/auth/webauthn/login

Body

{ "credential": { ... } }

关闭 TOTP 认证:

POST /api/v1/auth/totp/disable

Body(如当前已启用,需带上验证码确认):

{
  "totp_code": "123456"
}

2. 管理员邀请外方教师注册

POST /api/v1/users/invite-foreign

Body

{
  "email": "teacher@school.edu",
  "full_name": "John Smith"
}

3. 邮箱注册(外方教师)

POST /api/v1/auth/register/email

Body

{
  "email": "teacher@school.edu",
  "password": "12345678",
  "full_name": "John Smith"
}

说明:

  • 注册成功后自动登录

  • 新用户默认角色为 foreign_teacher

4. 获取当前登录用户信息

GET /api/v1/auth/me

5. 用户列表(管理员)

GET /api/v1/users

Query

  • role(可选)

  • status(可选)

  • search(可选,匹配姓名/学号/工号)

  • page, page_size(兼容 size)

6. 创建用户(superadmin / secretary)

POST /api/v1/users

Body:

{
  "user_code": "2024123456",
  "username": "zhangsan",
  "full_name": "张三",
  "email": "zhangsan@school.edu",
  "roles": ["student"],
  "password": "optional_password"
}

说明:

  • 未提供密码时,默认密码为 defaultPass123

7. 更新用户信息(superadmin / secretary)

PUT /api/v1/users/{id}

8. 修改角色(superadmin)

PUT /api/v1/users/{id}/role

Body:

{ "role": "assistant" }

9. 禁用/启用账户(superadmin / secretary)

PUT /api/v1/users/{id}/status

Body:

{ "status": "active" }

10. 导入人员 Excel(superadmin / secretary)

POST /api/v1/users/import
Content-Type: multipart/form-data

字段:

  • file:Excel 文件

表头约定:

  • 必填:学号 / 工号 / user_code / 学号/工号,以及 姓名 / full_name

  • 可选:用户名 / username邮箱 / email角色 / role

  • 用户名 为空时,后端会回退使用 user_code

  • 角色 为空时,默认使用 student

  • 模板不再包含 password 列;即使 Excel 中携带该列,后端也不会将其作为登录密码导入

导入策略:

  • 以后端 user_code 作为唯一键;已存在用户会被跳过,不做覆盖

  • 新导入用户统一创建为 active 状态,并调用 Django set_unusable_password() 设置不可用密码

  • 如需密码登录,请在导入完成后由管理员通过用户编辑接口单独设置密码

11. 刷新 Token

POST /api/v1/auth/token/refresh

Body(小程序场景):

{
  "refresh": "refresh_token_here"
}

说明:

  • Web 端:从 HttpOnly Cookie 中自动读取 refresh_token

  • 小程序:需在请求体中提供 refreshrefresh_token 字段

12. 登出

POST /api/v1/auth/logout

说明:

  • 清除认证 Cookie(Web 端)

13. 微信绑定

将当前登录用户与微信 openid 绑定,绑定后可使用微信一键登录。

POST /api/v1/auth/wechat/bind

Body:

{
  "code": "小程序 wx.login() 返回的临时登录凭证"
}

权限:需要登录。

14. 微信解绑

解除当前用户与微信的绑定。

POST /api/v1/auth/wechat/unbind

权限:需要登录。

15. 获取 SM2 公钥

用于前端加密敏感数据(如密码传输)。

GET /api/v1/accounts/sm2/public-key

权限:无需登录。

响应:

{
  "code": 0,
  "message": "success",
  "data": {
    "public_key": "SM2公钥字符串",
    "fingerprint": "公钥指纹"
  }
}