用户认证接口


Member 对象

字段 类型 说明
id string 会员 ID(Snowflake)
username string 用户名(注册时提交的账号原值:手机号或邮箱);游客为客户端随机生成(g 开头 + 字母数字,见【游客注册】)。用户名一经创建不可修改
nickname string 昵称
head_portrait string 头像 URL;注册时若商户配置了预设头像则随机分配一张(见【可选头像列表】),否则为空串
merchant_id string 所属商户 ID
register_type string 注册方式,phone 手机号 / email 邮箱 / guest 游客(见【游客注册】);存量会员为 phone。这是注册来源,【绑定账号】转正后不变;判断当前是否游客请看 is_guest
is_guest bool 是否游客。【游客注册】创建的账号为 true;【绑定账号】并设置密码转正后变为 false。客户端应据此展示「绑定账号 / 设置密码」引导,而非 register_type
phone string 登录手机号(纯号码,不含区号)。手机号注册时写入;存量会员与未配置区号商户的部分会员可能为空串
area_code string 国际手机区号(纯数字,如 55),未配置时为空串
email string 邮箱(服务端已归一化为小写)。邮箱注册时即登录邮箱;手机号注册的会员该字段也可能是 PIX 收款资料填写的收款邮箱——两种来源共用同一字段,同商户内唯一
phone_verified bool 手机号是否已通过真实性验证。当前注册流程不做任何验证,恒为 false;该字段是预留给提款等敏感操作的风控门槛,与能否登录无关
email_verified bool 邮箱是否已通过真实性验证。当前注册流程不做任何验证,恒为 false;用途同 phone_verified,与能否登录无关
channel_id string 渠道 ID
source string 来源标记
inviter_id string 直接上级会员 ID(无上级时为 "0")
promoter_code string 自己的推广码
current_level number 当前等级
is_ad_reported bool 是否已上报广告归因
reported_at string 广告归因上报时间
auto_withdraw number 自动提现规则,0 默认 / 1 自动 / 2 禁止
register_ip string 注册 IP
is_active bool 是否启用
last_login string 上次登录时间
date_joined string 加入时间
created_at string 创建时间
updated_at string 更新时间

游客的账号密码由客户端在【游客注册】时自行随机生成并持久化,服务端不会在任何接口返回密码(含本对象)。


注册

注册成功后自动登录并返回 token。

URL: POST /auth/register

输入:

字段 类型 必填 说明
username string 是 账号,长度 2-64。account_type=phone 时传手机号(纯号码,不含区号);account_type=email 时传邮箱
password string 是 密码,长度 4-64
account_type string 否 账号类型:phone 手机号 / email 邮箱。留空按 phone 处理,旧客户端不传时行为与之前完全一致;传枚举以外的值会被参数校验拦截(400),不会创建账号
nickname string 否 昵称,长度不超过 60
promoter_code string 否 邀请人的推广码,长度不超过 50
channel_id string 否 渠道 ID
source string 否 来源标记,pwa、h5 等;传 pwa 时服务端同时标记为 PWA 用户(浏览器注册后再安装 PWA 的场景见【上报 PWA 安装态】)
link_queries string 否 落地页 URL 的完整 query string,原样传入(可带 ? 前缀),长度不超过 1024。服务端会从中解析 fbclid 参数,构造 Facebook 点击 ID(fb.1.{注册时刻毫秒}.{fbclid})存库,用于后续 Facebook 广告归因上报(FB CAPI)——投放场景务必透传,勿丢弃 fbclid。APK / IPA WebView 场景:原生包会在 URL 上追加 app_id / appsflyer_id / adid / advertising_id / device_id(AppsFlyer / Adjust SDK 生成的归因与设备标识),服务端据此向 MMP 上报注册与首充事件;H5 必须在页面跳转 / 登录 / 注册全程保留并原样传入,缺 adid 与 appsflyer_id 时服务端不上报(AppsFlyer 链路还需 app_id)
area_code string 否 国家手机区号(纯数字,如 55)。商户已配置区号时,缺省则服务端填充;若传入必须等于商户配置值。最大 8 字符

当 account_type 省略或为 phone 时

  • username 即手机号,同时写入会员的 username 与 phone 字段,同商户内手机号唯一
  • 手机号校验说明:仅当商户在总后台配置了国家手机区号时,才用对应正则校验 username 并校验 area_code 与商户配置一致;商户未配置区号则区号与号码格式均不校验(兼容存量商户)

当 account_type=email 时

  • username 传邮箱;服务端将其归一化(去首尾空格 + 转小写)后存入 email 字段作为登录标识,因此 A@B.com 与 a@b.com 视为同一账号
  • 邮箱格式非法返回业务错误 邮箱格式不正确;同商户内邮箱唯一(与其他会员填写的 PIX 收款邮箱共用同一唯一空间)
  • 不做任何区号 / 手机号格式校验,phone 字段留空
  • 注册不发送验证邮件,email_verified 保持 false(见 Member 对象)

请求示例 —— 手机号注册(与旧版本完全一致,无需改动):

curl -X POST 'https://<your-domain>/api/game/auth/register' \
  -H 'Content-Type: application/json' \
  -d '{
    "username": "11987654321",
    "password": "abc12345",
    "area_code": "55",
    "source": "h5"
  }'

请求示例 —— 邮箱注册:

curl -X POST 'https://<your-domain>/api/game/auth/register' \
  -H 'Content-Type: application/json' \
  -d '{
    "username": "Player@Example.com",
    "password": "abc12345",
    "account_type": "email",
    "source": "h5"
  }'

输出:

字段 类型 说明
token string access jwt token
user_id string 会员 ID

业务错误:

message 触发条件
手机区号与商户配置不一致 客户端传入的 area_code 与商户配置值不一致
手机号格式不正确 商户已配置区号时,username(=手机号)不匹配商户区号对应的正则
邮箱格式不正确 account_type=email 时 username 不是合法邮箱地址
该手机号已被注册 同商户内该手机号已存在
该邮箱已被注册 同商户内该邮箱已存在(按归一化后的值比对)
账号已存在 同商户内 username 原值已被占用
注册失败,请重试 并发注册同一账号时命中唯一约束的兜底提示,可换账号或重试操作过于频繁,请稍后再试
---

登录

URL: POST /auth/login

输入:

字段 类型 必填 说明
username string 是 账号,长度 2-64。login_type=phone 时传手机号(纯号码,不含区号);login_type=email 时传邮箱;login_type=guest 时传【游客注册】返回的 username
password string 是 密码,长度 4-64。login_type=guest 时传【游客注册】返回的 password
login_type string 否 登录方式:phone 手机号 / email 邮箱 / guest 游客。留空按 phone 处理,旧客户端不传时行为与之前完全一致;传枚举以外的值会被参数校验拦截(400)

当 login_type 省略或为 phone 时

  • 先按 phone 字段匹配;未命中时自动降级按 username 匹配,因此存量会员与未配置区号商户的会员照常登录

当 login_type=email 时

  • 输入邮箱先归一化(去首尾空格 + 转小写)再匹配 email 字段,大小写不敏感
  • 登录不检查 email_verified / phone_verified:这两个字段仅用于提款等敏感操作的风控,与能否登录无关

当 login_type=guest 时

  • 按 username 精确匹配,用于客户端用本机保存的游客账号密码自动登录(玩家不填任何东西)
  • 游客已通过【绑定账号】转正后,游客密码已被用户自填密码覆盖,本机那副旧凭证再登录会返回 账号或密码错误——客户端应在转正成功时立即清除本机游客凭证,不给免密进会员账号留后门

请求示例 —— 邮箱登录:

curl -X POST 'https://<your-domain>/api/game/auth/login' \
  -H 'Content-Type: application/json' \
  -d '{
    "username": "Player@Example.com",
    "password": "abc12345",
    "login_type": "email"
  }'

输出:

字段 类型 说明
token string access jwt token
user_id string 会员 ID

业务错误:

message 触发条件
账号或密码错误 账号不存在或密码错误。两种情况返回同一文案(防账号枚举),⚠️ 客户端不得据此判断账号是否已注册
会员已被禁用 账号密码正确,但该会员已被商户停用
操作过于频繁,请稍后再试 登录失败次数超限:同一账号 10 分钟内失败 ≥ 10 次,或同一 IP 10 分钟内失败 ≥ 50 次;窗口内该账号 / IP 的后续登录均被拒绝,成功登录不计数

游客注册

免填表开号:客户端自行随机生成一副账号密码提交,服务端据此创建游客账号并直接签发登录 token。玩家一个字不用填,也不经手这副账号密码。免登录;需商户在后台开启「允许游客登录」(默认关闭)。

URL: POST /auth/guest_register

输入:

字段 类型 必填 说明
username string 是 客户端随机生成的游客账号,长度 8-64,必须匹配 ^g[A-Za-z0-9]{7,63}$(小写 g 开头 + 字母数字)。建议 g + 12 位以上随机字母数字,商户内唯一;撞名返回 账号已存在,客户端重新生成再试
password string 是 客户端随机生成的游客密码,长度 8-64。建议用 crypto.getRandomValues 生成 32 位以上
promoter_code string 否 邀请人的推广码,长度不超过 50
channel_id string 否 渠道 ID,长度不超过 50
source string 否 来源标记,pwa、h5 等,长度不超过 100;传 pwa 时服务端同时标记为 PWA 用户(其它场景见【上报 PWA 安装态】)
link_queries string 否 落地页 URL 的完整 query string,长度不超过 1024,语义与【注册】相同(解析 fbclid 用于广告归因;APK / IPA 场景的 MMP 归因参数同样须原样透传)

行为说明

  • 每次调用都新开一个账号:username / password 原值落库(密码哈希存储),register_type = guest,is_guest = true
  • ✅ 客户端必须在调用前把这副 username / password 持久化到本机(与伪设备号同存同退):它们是该游客账号唯一的登录凭证,服务端不会在任何接口返回密码;丢失即无法再登录该账号,泄露即他人可登录。玩家不经手也不可见,客户端不要展示
  • 游客登录:本机存有这副凭证时,调【登录】传 login_type=guest + 保存的 username / password 自动登录,用回原账号(余额、奖金、记录都在);本机没存才生成新凭证调本接口开新号。✅ 不要每次启动都调本接口,否则会不断造新号
  • 游客账号特性(【Member 对象】is_guest=true):
    • 不可提现:【创建提现订单(统一)】与【创建 PIX 提现】返回业务错误 游客账号不支持提现,请先绑定正式账号
    • 拥有免费账户(体验金):【免费注册奖金】开启时,本接口即是该活动的唯一领取入口:注册事务内一次性发放、用完不补,余额见【账户余额】的 free_money;可用【免费账户启动游戏】试玩(目前仅 365 平台游戏)。免费余额与真实余额完全隔离,不可提现、不计打码、不触发活动。调用前建议先调【领取资格】
    • 通过【绑定账号】绑定手机/邮箱并设置密码后转正(is_guest 变为 false),解除上述提现限制;转正不影响免费账户(余额、倒计时、活动状态均不变,免费账户的锁定/拆笔只由充值驱动);转正时游客密码被用户自填密码覆盖,本机那副旧凭证随即失效,客户端应同时清除它
  • 并发造号防护:同一 IP 1 分钟内超过 10 次即拒绝(见下方业务错误)
  • 其余登录后行为(token 有效期、/auth/detail 续签等)与密码登录完全一致

请求示例:

curl -X POST 'https://<your-domain>/api/game/auth/guest_register' \
  -H 'Content-Type: application/json' \
  -d '{
    "username": "g7k2m9x4qp1z",
    "password": "Zt8vQ2nL5wR9kX3mB7cD1fH4jP6sV0yA",
    "source": "pwa"
  }'

输出:

字段 类型 说明
token string access jwt token
user_id string 会员 ID

业务错误:

message 触发条件
游客账号格式不正确 username 不匹配 ^g[A-Za-z0-9]{7,63}$(长度不合法则被参数校验拦截,400)
账号已存在 同商户内 username 已被占用,客户端重新生成再试
注册失败,请重试 并发注册同一账号时命中唯一约束的兑底提示,重新生成再试
当前商户未开放游客登录 商户未在后台开启「允许游客登录」
无效的推广码 promoter_code 不存在
同IP注册人数已达上限 命中商户同 IP 注册数风控
当前网络领取免费奖金的次数已达上限 【免费注册奖金】开启且该 IP 领取次数已达 ip_claim_limit(非白名单),注册整体失败
操作过于频繁,请稍后再试 同一 IP 1 分钟内调用本接口超过 10 次(无论成功与否)

获取登录用户详情

URL: GET /auth/detail

输出:

字段 类型 说明
... Member 用户信息(含 is_guest,见【Member 对象】)
new_token string 新签发的 JWT(可选,仅当当前 token 剩余有效期 < 30 天时返回)

Token 自动续签: JWT 总有效期为 30 天。当服务端检测到当前 token 剩余有效期不足 30 天时,会在响应体顶层追加 new_token 字段,包含一个新签发的 JWT。前端收到该字段后应立即替换本地存储的 token,后续请求使用新 token。旧 token 不会被吊销,在自然过期前仍可使用。


绑定账号

为当前登录会员绑定手机号或邮箱。需登录。游客借此转正(同时设置密码);普通会员用于补绑另一种账号。

URL: POST /auth/bind_account

输入:

字段 类型 必填 说明
account_type string 是 绑定类型:phone 手机号 / email 邮箱。传枚举以外的值会被参数校验拦截(400)
account string 是 账号,长度 2-64。account_type=phone 时传手机号(纯号码,不含区号);account_type=email 时传邮箱
password string 条件 密码,长度 4-64。游客必填(转正同时设置密码);非游客必须留空
area_code string 否 国家手机区号(纯数字,如 55),最大 8 字符,仅 account_type=phone 时有意义。商户已配置区号时,缺省则服务端填充;若传入必须等于商户配置值

游客(is_guest=true)

  • 必须同时传 password,绑定成功即转正:is_guest 变为 false,解除提现限制
  • 之后用【登录】密码登录(login_type 对应 phone / email,username 传绑定的手机号 / 邮箱),换设备也能登录
  • ⚠️ 传入的 password 会覆盖【游客注册】时客户端随机生成的游客密码,本机那副游客凭证随即失效(再用它 login_type=guest 登录返回 账号或密码错误)。客户端应在转正成功时立即清除本机游客凭证并隐藏「游客登录」入口
  • register_type 与 username 不变(仍为 guest / 注册时随机生成的用户名)——它们是注册来源,判断当前是否游客请以 is_guest 为准

非游客

  • 仅补绑手机或邮箱,不传 password(传了返回业务错误 当前账号已设置密码,请勿重复提交)
  • 每个槽位只能绑一次:已有 phone 不可再绑手机,已有 email 不可再绑邮箱(含手机号注册会员因 PIX 收款资料 已写入的 email)

校验规则(与【注册】一致)

  • 手机号:仅当商户配置了区号时才校验号码格式与 area_code 一致性;商户未配置则不校验。同商户内手机号唯一
  • 邮箱:服务端归一化(去首尾空格 + 转小写)后校验格式并存储;同商户内邮箱唯一(与其他会员的 PIX 收款邮箱共用同一唯一空间)
  • 绑定不发送验证短信 / 邮件,phone_verified / email_verified 保持 false

请求示例 —— 游客绑定手机号并设置密码(转正):

curl -X POST 'https://<your-domain>/api/game/auth/bind_account' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <jwt>' \
  -d '{
    "account_type": "phone",
    "account": "11987654321",
    "area_code": "55",
    "password": "abc12345"
  }'

请求示例 —— 普通会员补绑邮箱:

curl -X POST 'https://<your-domain>/api/game/auth/bind_account' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <jwt>' \
  -d '{
    "account_type": "email",
    "account": "Player@Example.com"
  }'

输出: 无

业务错误:

message 触发条件
游客绑定账号需同时设置密码 游客调用时未传 password
当前账号已设置密码,请勿重复提交 非游客调用时传了 password
已绑定手机号,不可重复绑定 account_type=phone 但会员 phone 已有值
已绑定邮箱,不可重复绑定 account_type=email 但会员 email 已有值
手机区号与商户配置不一致 客户端传入的 area_code 与商户配置值不一致
手机号格式不正确 商户已配置区号时,account 不匹配商户区号对应的正则
邮箱格式不正确 account_type=email 时 account 不是合法邮箱地址
该手机号已被注册 同商户内该手机号已被其他会员占用
该邮箱已被注册 同商户内该邮箱已被其他会员占用(按归一化后的值比对)
操作过于频繁,请稍后再试 同一会员 10 分钟内调用本接口超过 10 次(无论成功与否)

修改密码

URL: POST /auth/change_password

输入:

字段 类型 必填 说明
old_password string 是 旧密码,长度 4-64
new_password string 是 新密码,长度 4-64,不能与旧密码相同

输出: 无


修改用户资料

URL: POST /auth/update

输入:

字段 类型 必填 说明
nickname string 否 昵称,长度不超过 60
head_portrait string 否 头像 URL,长度不超过 1000;建议通过 获取上传预签名 URL 上传后填入返回的公开访问地址

输出: 无


退出登录

URL: POST /auth/logout

输入: 无

输出: 无