加载中…
鉴权与会话

鉴权模型

API 使用 Bearer Token 鉴权,令牌与设备(客户端实例)一一对应:

Authorization: Bearer 3f8c2e...(64 位十六进制)
  • 登录接口成功后由响应 data.user.token 下发;
  • 服务端只存令牌的 sha256 摘要(不存明文),泄漏面小;
  • 有效期 30 天,每次成功调用自动刷新最后活动时间续期(写库有 60 秒节流,无额外压力);
  • 每个登录设备一个独立令牌,多端登录互不影响;退出登录只吊销当前令牌。

鉴权级别(三态):

级别 行为
公开(public) 无须令牌,匿名可调
可选(optional) 带令牌返回个性化数据(如"我是否已收藏"),不带也能调
必须(required) 无有效令牌返回 401 UNAUTHORIZED

另有「工作端」子策略:标记了 work_required 的接口除登录外还要求当前令牌绑定员工身份,否则返回 403 FORBIDDEN(详见《工作端接口》)。

未命中鉴权要求的响应示例:

{
  "code": "UNAUTHORIZED",
  "message": "登录已超时,请重新登录",
  "data": {},
  "errors": {},
  "request_id": "9f2a5c8e1b3d7f40"
}

登录接口的公共结构

三种登录方式(账号密码、手机验证码、注册即登录)成功响应结构一致:

{
  "code": "OK",
  "message": "",
  "data": {
    "user": {
      "user_id": 12,
      "token": "3f8c2e...(64 位十六进制)",
      "field": "email"
    },
    "dou": {
      "auth": {
        "is_work": false
      }
    }
  },
  "errors": {},
  "request_id": "9f2a5c8e1b3d7f40"
}
字段 说明
data.user.user_id 会员 ID
data.user.token API 会话令牌,客户端持久化并在后续请求携带
data.user.field 账号类型:email(邮箱)/ mobile(手机号)
data.dou.auth.is_work 是否绑定员工身份(决定工作端入口是否可用)

验证码下发流程(注册 / 手机登录共用)

注册表单和手机验证码登录依赖「图形令牌 + 短信/邮件验证码」两步流程:

第 1 步:获取图形令牌对

GET /api/captcha/token
{
  "code": "OK",
  "message": "",
  "data": {
    "captcha_token": "...",
    "storage_captcha_token": "..."
  },
  "errors": {},
  "request_id": "9f2a5c8e1b3d7f40"
}

注册表单接口 user/register 也会顺带下发这对令牌(连同 promotion_user_sn、sns_token 等注册上下文),客户端只需在表单初始化时调一次即可。

第 2 步:下发短信 / 邮件验证码

POST /api/captcha/verification
Content-Type: application/json

{
  "type": "sms",                 // sms=短信 / email=邮件
  "account": "13800000000",      // 接收账号(手机号或邮箱)
  "captcha_token": "...",        // 第 1 步返回
  "storage_captcha_token": "...",// 第 1 步返回
  "check": "no_allow_phone_exist" // 业务策略:注册场景用默认值(拦截已注册账号);登录场景传空串
}

成功响应 data 即「验证数据」(verification_data):

{
  "code": "OK",
  "message": "",
  "data": {
    "account": "13800000000",
    "ontime": 1760000000,
    "code": "服务端生成的验证码校验摘要"
  },
  "errors": {},
  "request_id": "9f2a5c8e1b3d7f40"
}

重要约定:data 的内容由服务端签发(内含验证码校验摘要与发送时间 ontime),客户端原样保存、原样透传给注册 / 登录提交接口(作为 verification_data,JSON 字符串或对象均可,服务端会自动解析),不要修改或解析。验证码有效期 5 分钟;过期或与账号不匹配会返回 422,errors.verification 给出具体原因。

接口清单

方法 路径 鉴权 说明
GET /api/user/register 公开 注册表单上下文(下发令牌对与注册配置)
POST /api/user/register_post 公开 注册提交(成功后直接登录,返回令牌)
POST /api/user/login_post 公开 账号密码登录
POST /api/user/login_phone_post 公开 手机验证码登录
GET /api/user/password_reset 公开 忘记密码表单(返回页面标题)
POST /api/user/password_reset_post 公开 忘记密码提交(向邮箱发送重置链接邮件)
POST /api/user/logout 必须 退出登录(吊销当前令牌)
POST /api/user/check_login_state 公开 检查登录态(未登录不报 401)

注册

表单上下文 GET /api/user/register?user_sn=xxx&sns_token=yyy(参数均可选):

{
  "code": "OK",
  "message": "",
  "data": {
    "captcha_token": "...",
    "storage_captcha_token": "...",
    "promotion_user_sn": "xxx",
    "sns_token": "yyy",
    "login_mode": "email",
    "mail_username": 1,
    "sms_accessKeyId": 0
  },
  "errors": {},
  "request_id": "9f2a5c8e1b3d7f40"
}
字段 说明
login_mode 站点注册方式:email / (短信)
mail_username 1=已配置邮件发信,邮箱验证码区可展示
sms_accessKeyId 1=已配置短信通道,短信验证码区可展示

注册提交 POST /api/user/register_post:

参数 必填 说明
email 或 mobile 二选一 提供哪个走哪种注册方式;邮箱走 email,手机走 mobile
password 是 密码
password_confirmation 是 确认密码(须一致)
verification 条件 当站点开启了邮箱/短信验证时必须提供(第 2 步发的验证码)
verification_data 条件 第 2 步返回的验证数据(JSON 字符串,原样透传)
promotion_user_sn 否 推广人编号(分销场景透传)
sns 否 第三方绑定数据(JSON 字符串,登录后自动关联)

成功响应同「登录接口的公共结构」,客户端拿 data.user.token 即可开始调用其它接口。

账号密码登录

POST /api/user/login_post
Content-Type: application/json

{ "username": "user@example.com", "password": "******" }
  • username 可填邮箱或手机号(field 自动识别);
  • 失败返回 422,errors 中给出账号或密码错误原因(出于安全,不区分"账号不存在"与"密码错误");
  • 该接口限流 5 次/60 秒。

手机验证码登录

POST /api/user/login_phone_post
Content-Type: application/json

{
  "mobile": "13800000000",
  "verification": "123456",
  "verification_data": { "...": "第 2 步返回,原样透传" },
  "promotion_user_sn": ""
}
  • 第 2 步下发验证码时 check 传空串(登录场景不拦截已存在账号,反而要求账号存在);
  • 登录成功若账号尚未注册会按站点策略自动处理(以实际返回为准);
  • 该接口限流 5 次/60 秒。

忘记密码

  1. POST /api/user/password_reset_post,参数 email(必须为已注册邮箱):
    • 邮箱不存在 → 404 NOT_FOUND,errors.email 提示;
    • 发送失败 → 500 SERVER_ERROR;
    • 成功 → 200 OK,message 提示已发送(邮件内含带 uid 与 code 的重置链接,点开在网页端继续重置)。
  2. GET /api/user/password_reset 仅返回表单标题,供客户端渲染页面头部。

该接口限流 5 次/300 秒。

登录态检查与退出

检查登录态 POST /api/user/check_login_state:

// 已登录
{ "code": "OK", "message": "", "data": { "login_state": true }, "errors": {}, "request_id": "..." }
// 未登录(注意:HTTP 仍是 200,不报 401)
{ "code": "OK", "message": "", "data": { "login_state": false }, "errors": {}, "request_id": "..." }

适合应用启动时静默探测本地令牌是否仍有效,不触发 401 错误流。

退出登录 POST /api/user/logout(须带令牌):

{ "code": "OK", "message": "", "data": {}, "errors": {}, "request_id": "..." }

吊销当前设备令牌;其它设备已下发的令牌不受影响。客户端应同时清空本地令牌。

令牌失效排查

收到 401 UNAUTHORIZED 时按客户端的标准动作处理:清除本地令牌 → 跳登录页。常见原因:

现象 原因
所有必须鉴权接口都 401 未带回 Authorization 头,或头格式缺 Bearer 前缀
单次偶发 401 令牌被其它设备退出、或后台吊销
登录后过一段时间开始 401 令牌超过 30 天未活动过期

修改密码与资料

均要求登录,详见《会员接口》:

接口 说明
POST /api/user/password_post 修改密码(old_password + password + password_confirmation);成功返回 data.relogin=true,建议客户端引导重新登录
GET /api/user/edit / POST /api/user/edit_post 资料编辑表单与保存
POST /api/user/upload_avatar 头像上传(multipart)
添加日期:2026-10-06