用户认证接口
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),未配置时为空串 |
| 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),解除上述提现限制;转正不影响免费账户(余额、倒计时、活动状态均不变,免费账户的锁定/拆笔只由充值驱动);转正时游客密码被用户自填密码覆盖,本机那副旧凭证随即失效,客户端应同时清除它
- 不可提现:【创建提现订单(统一)】与【创建 PIX 提现】返回业务错误
- 并发造号防护:同一 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
输入: 无
输出: 无