小米游戏联合登录方案V1.7(开发者版)更新时间:2025-09-19 14:57:00

1、方案简介

本方案为小米基于全新联运模式提供的联合登录方案,同时满足新/老用户的登录需求,帮助开发者快速、低成本构建游戏基本能力。

用户体验
首次登录,用户首次启动小米游戏时,小米游戏服务向用户展示欢迎引导页。

1. 用户点击“下一步”,小米游戏服务向用户展示联合登录面板。

2.基于用户选择的登录方式完成账号登录

a.用户点击“系统小米账号登录”,则进入系统小米账号登录流程。支持关联游戏官方登录和渠道账号直接登录

1.首次登录时将基于用户是否在当前游戏中存在既有渠道账号自动选择是否关联登录

2.关联登录用户可在游戏/游戏中心中完成账号解绑,解绑后用户可重新选择关联登录或直接登录

(仅解绑后登录展示该页面)

b.用户点击“游戏官方账号登录”,则进入游戏官方账号流程。

c.用户点击“其他方式登录”,则进入渠道账号登录流程

3.用户完成登录后,将对用户进行实名认证校验与未成年防沉迷校验。

用户根据引导完成首登进入游戏后,后续打开该游戏将不再展示欢迎引导页。


非首次登录
用户非首次启动游戏时,小米游戏服务会延用上次的游戏登录方式。涉及切换账号再登录等特殊场景的接入方式请参见切换账号。


登录场景介绍
游戏登录支持使用小米账号登录、游戏官方账号登录、其他账号登录。游戏调用联合登录接口时,向玩家展示小米账号和游戏官方账号联合登录面板;
支持玩家选择任意一种登录方式(游戏官方账号、小米账号以及其他账号)进入游戏;
用户解绑后并重新选择小米账号登录时,可选择是否关联登录。

名称解释

关联登录用户使用系统小米账号快速登入游戏,并选择与游戏官方账号完成关联,实现跨端、跨品牌、跨系统游戏账号互通的游戏体验
直接登录用户使用系统小米账号快速登入游戏,并不希望与游戏官方账号完成关联(或已存在既有小米渠道账号),将继续登入小米渠道账号
游戏官方账号登录用户选择登入游戏官方账号,需要由开发者展示登录UI

2、开发准备

创建游戏

  • 统一包的上架流程,上架游戏合作类型选择其它,此模式下免去.mi结尾的包名校验,并跳过传统联运协议签署环节(需注意线下协议签署);
  • 其他上架提审/版本更新流程与原联运流程一致;

  • 如需迁移原小米包预约用户/评论信息/社区内容等,请联系商务与运营对接处理;
  • 如此游戏之前已通过小米包内测,需同步内测期间用户游戏信息,联系商务与运营对接处理。



联合登录配置

  • 支持配置是否支持官方账号
  • 支持配置是否支持关联登录
  • 支持配置官方账号登录入口样式
    • 样式一:登录按钮,支持配置按钮文案,用户选择后返回的accountType为official_account
    • 样式二:图标按钮,支持配置1~4个图标并指定每个图标对应的accountType (暂不支持,后续版本提供)

关联场景配置(账号维度的关联,将小米账号关联至游戏官方账号)

  • 请选择是否支持关联登录,如果支持,请选择关联方式为手机号关联,或自行关联
    • 如果支持关联,请选择关联的维度为游戏维度 或 开发者维度(建议选择开发者维度)
      • 返回给开发者的unionid是游戏维度/开发者维度。

    • 如果支持关联,需要配置解除关联回调地址,当用户注销小米账号/在游戏中心取消关联时,小米游戏服务将通过回调接口通知游戏侧解除关联关系,解除后用户仍可通过游戏官方账号登入该账号
    • 如果不支持关联,用户在联合登录流程中将会默认走直接登录流程

3、接入流程

3.1、接口说明

接口名称接口含义接口参数回调参数调用时机是否必须调用
checkIsXiaomi判断当前是否小米设备return true: 是小米手机 false: 非小米手机游戏CTA同意后,任何需要判断是否为小米设备的场景
init初始化接口:游戏CTA同意后调用,初始化运行配置,应用鉴权InitCallback:初始化结果回调onInitSuccess 初始化成功
onError 初始化校验失败
errCode:错误码
errMsg:错误信息
游戏CTA同意后,每次冷启动都需要调用一次
unionLogin联合登录接口:支持用户选择系统小米账号登录(直接登录 / 关联),支持用户登入游戏官方账号,并对用户进行实名和未成年防沉迷Activity:当前前台Activity
UnionLoginParam:登录参数
changeAccount:是否切换账号
LoginPanelType :登录入口类型,支持按钮和图标
UnionLoginCallback:登录回调
onLoginSuccess 登录成功
UnionLoginResult
accountType:账号类型 official_account 官方账号登录 mi_account 小米账号登录
uid:用户id accountType为mi_account有效,isBinding为true时返回关联使用的uid(unionId), isBinding为false时返回直接登录使用的uid(openId
serviceToken:登录token,用于后续的服务器请求
isBinding:是否为关联登录
bindType:关联类型 1:手机号关联 2:非手机号关联
bindDimension:关联维度 1:游戏级别 2:开发者级别
gameId:当前关联的游戏账号id 来自开发者回传的开发者级别/游戏级别的openId 与uid完成关联
onLoginCancel 登录取消
onError 登录失败
errCode:错误码
errMsg:错误信息
init初始化接口调用并回调初始化完成之后
bindAccount关联登录上报接口:用户选择系统小米账号关联登录时,同意授权手机号给游戏后,unionLogin接口返回isBinding为true时,游戏完成账号关联或者注册后通知小米游戏侧Activity:当前前台Activity
BindAccountParam:关联登录参数
bindStatus:是否关联完成
uid:unionLogin关联场景返回的uid
gameId:开发者关联的账号唯一id
BindAccountCallback:关联回调
onBindSuccess 关联状态记录完成
onError 关联失败(不阻塞主流程)
errCode:错误码
errMsg:错误信息
unionLogin接口调用完成,返回了isBinding为true时,游戏内部基于手机号完成账号关联或者注册后
unBindAccount
(提供服务端接口)
解绑接口:用户在游戏内主动取消关联,游戏完成账号关联取消后,通知小米侧账号已完成解绑
解绑后,用户可以继续使用游戏官方账号登入该游戏,但不能使用小米账号登入,下次联合登录是用户可重新选择登录方式
Activity:当前前台Activity
UnbindAccountParam:解除关联参数
uid:unionLogin关联场景返回的uid
gameId:开发者关联的账号唯一id
UnBindAccountCallback:解除关联结果回调
onUnBindSuccess 解除关联状态记录完成
onError 解除关联状态记录失败(不阻塞主流程)
errCode:错误码
errMsg:错误信息
用户在游戏内部主动发起解绑时
reportGameRole角色信息上报接口:游戏侧完成账号校验和登录流程后,客户端调用该接口上报游戏角色信息,核心作用为通知小米侧用户已进入游戏Activity:当前前台Activity
MiRoleInfo:游戏角色信息
roleId:角色ID: 必传字段、不可为空
roleName:角色名称: 必传字段、不可为空
roleLevel:角色等级: 非必传字段
realmId:区服ID: 非必传字段
realmName:区服名称: 非必传字段
ReportGameRoleCallback:角色上报结果回调
onReportSuccess 角色上报完成
onError 角色上报失败(不阻塞主流程)
errCode:错误码
errMsg:错误信息
游戏侧完成用户登录并获取到用户的游戏角色信息后,代表正式进入游戏
verifyGamePlayer实名与防沉迷校验接口:基于系统小米账号对用户进行实名与防沉迷Activity:当前前台Activity
VerifyGamePlayerCallback:校验结果回调
onVerifyPass 校验通过,可正常进入游戏
onError 校验失败,需提示用户无法进入游戏
errCode:错误码
errMsg:错误信息
init初始化接口调用并回调初始化完成之后
registerAntiListener注册监听器获取实时用户未成年监控状态GameAntiStatusCallback:防沉迷状态回调isNeedLimit 用户实名信息 0:未知 1:成年人 2:未成年人
dayLeftMills 用户剩余可玩时间
init初始化接口调用并回调初始化完成之后

3.2、关联登录流程(游戏官服)

  1. 玩家启动游戏
  2. 游戏弹出隐私协议弹窗
  3. 用户同意隐私协议后,调用checkMiDevice接口确认是否为小米设备,如果返回的设备类型为小米设备,则应走小米游戏服务的联合登录流程,否则直接走游戏官方登录流程即可。
  4. 小米设备的情况下,调用init接口初始化游戏服务SDK,初始化完成后才能继续调用后续接口。
  5. 用户触发登录
  6. 调用unionLogin接口
  7. 游戏服务向用户展示联合登录弹窗
  8. 如果用户选择小米账号快速登录 并且 选择新用户/关联登录,将走关联登录流程
  9. 如果游戏配置了使用手机号完成关联 并且 用户未授权给该游戏时,将展示用户授权(基础账号信息+手机号)弹窗
  10. 用户完成授权后,游戏服务对用户进行实名和防沉迷校验
  11. 通过后,游戏服务回调返回accountType、unionId、isBinding、token、gameId等信息
  12. 游戏服务端使用token校验登录参数的合法性,同时获取用户完整信息,isBinding = true代表关联场景,gameId为空代表游戏服务侧当前无关联记录,需要游戏侧完成账号关联并通知游戏服务
  13. 【子分支1】当游戏配置了基于手机号关联,同时用户同意授权手机号时,token校验结果将包含用户完整手机号,开发者服务端基于手机号查询是否存在既有账号,如果有,则进行关联,如果没有,则自动创建新账号。关联的是unionLogin返回的unionId和游戏内部开发者维度账号gameId,最后把登录结果返回游戏客户端(包含关联结果)
  14. 【子分支2】当用户未同意授权手机号 或者 游戏配置了不基于手机号关联时,token校验结果将不包含手机号,开发者服务端基于unionId查询是否已关联游戏官方账号
  15. 【子分支2】如果没有关联记录,游戏应引导用户完成游戏官方账号登录(相比普通登录流程,应明示将关联至当前小米账号)
  16. 【子分支2】用户完成登录后,游戏服务端完成unionId和游戏内部开发者维度账号gameId的关联,并返回关联结果
  17. 关联流程结束后,调用bindAccount接口上报关联结果至游戏服务
  18. 游戏内对用户进行实名和防沉迷校验
  19. 通过后调用reportGameRole接口上报角色信息

3.3、游戏官方账号登录流程(游戏官服)

  1. 玩家启动游戏
  2. 游戏弹出隐私协议弹窗
  3. 用户同意隐私协议后,调用checkMiDevice接口确认是否为小米设备,如果返回的设备类型为小米设备,则应走小米游戏服务的联合登录流程,否则直接走游戏官方登录流程即可。
  4. 小米设备的情况下,调用init接口初始化游戏服务SDK,初始化完成后才能继续调用后续接口。
  5. 用户触发登录
  6. 调用unionLogin接口
  7. 游戏服务向用户展示联合登录弹窗
  8. 如果用户选择游戏官方账号登录,将走游戏官方账号登录流程
  9. 游戏服务对用户进行实名和防沉迷校验
  10. 通过后,游戏服务回调返回accountType等信息
  11. 游戏官方账号登录流程
  12. 游戏内对用户进行实名和防沉迷校验
  13. 调用reportGameRole接口上报角色信息

3.4、直接登录流程(渠道服)

  1. 玩家启动游戏
  2. 游戏弹出隐私协议弹窗
  3. 用户同意隐私协议后,调用checkMiDevice接口确认是否为小米设备,如果返回的设备类型为小米设备,则应走小米游戏服务的联合登录流程,否则直接走游戏官方登录流程即可。
  4. 小米设备的情况下,调用init接口初始化游戏服务SDK,初始化完成后才能继续调用后续接口。
  5. 用户触发登录
  6. 调用unionLogin接口
  7. 游戏服务向用户展示联合登录弹窗
  8. 如果用户选择小米账号快速登录 并且 选择老用户/直接登录,或选择其他登录方式,将走直接登录流程
  9. 将展示用户登录授权(基础账号信息)弹窗
  10. 用户完成授权后,游戏服务对用户进行实名和防沉迷校验
  11. 通过后,游戏服务回调返回accountType、uid、token等信息
  12. 游戏服务端使用token校验登录参数的合法性,同时获取用户完整信息
  13. 校验通过后,开发者服务端基于uid完成游戏账号查询或注册,返回账号信息至客户端
  14. 调用reportGameRole接口上报角色信息

4、接入步骤

4.1、开发环境

  • JDK 1.8及以上
  • 安装AndroidStudio 3.6.1及以上
    • minSdkVersion 19及以上
    • targetSdkVersion 34(推荐)
    • compileSdkVersion 34(推荐)
    • Gradle 5.6.4及以上(推荐)

  • 测试游戏设备
    • 仅支持国内版MIUI手机

4.2、集成GameService SDK

1.本地依赖

暂不提供本地依赖


2.maven依赖

2.1 配置GameService SDK的Maven仓库地址

Android Studio的代码库配置在Gradle插件7.0以下版本、7.0及以上版本有所不同。请根据您当前的Gradle插件版本,选择对应的配置过程。

2.2 7.0以下版本

a.打开Android Studio项目级“build.gradle”文件。

b.在“buildscript > dependencies”中配置AndroidGradle插件版本不低于3.6.0。

c.在“allprojects > repositories”中配置小米游戏SDK的Maven仓地址。

buildscript {  
repositories {
google()
jcenter()
}
dependencies {
//确保该版本不低于3.6.0
classpath 'com.android.tools.build:gradle:3.6.3'

}
}
allprojects {
repositories {
配置小米的Maven仓库地址...
maven {
url "https://repos.xiaomi.com/maven"
credentials {
username 'mi-gamesdk'
password 'AKCp8mYeLuhuaGj6bK1XK7t2w4CsPuGwg6GpQdZ9cat7K59y5sD7Tx3dHjJcFrBGj3TQ4vi7g'
}
}
}
}

d.在“gradle-wrapper.properties ”中确保Gradle版本不低于5.6.4。

distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip

2.3 7.0及以上版本

打开项目级“settings.gradle”文件,配置小米游戏SDK的Maven仓地址。

dependencyResolutionManagement { 
...
repositories {
...
//增加小米SDK的Maven仓库地址
maven {
url "https://repos.xiaomi.com/maven"
credentials {
username 'mi-gamesdk'
password 'AKCp8mYeLuhuaGj6bK1XK7t2w4CsPuGwg6GpQdZ9cat7K59y5sD7Tx3dHjJcFrBGj3TQ4vi7g'
}
}
}
}

3.添加编译依赖

打开应用级的“build.gradle”文件。
在“dependencies”中添加如下编译依赖

dependencies {   
def gameserviceVersionName= "1.2.0"
implementation "com.xiaomi.ecosys:gameservice:$gameserviceVersionName"
}

注意:如果同时接入了IAP SDK,IAP SDK也需要升级至1.2.0,IAP接口无变化

4.AndroidManifest配置

将创建游戏后获得的AppId和AppKey配置到AndroidManifest.xml中

<application>  
...
<!-- 注意前缀mi_必须添加-->
<meta-data
android:name="miClientAppId"
android:value="mi_2882xxxxxxxxxx" />
<meta-data
android:name="miClientAppKey"
android:value="mi_xxxxxxxxx" />
...
<!-- ${applicationId} 替换为游戏包名 -->
<provider
android:name="com.xiaomi.ecosys.gameservice.provider.MiGameServiceProvider"
android:authorities="${applicationId}.mi_gs_provider"
android:enabled="true"
android:exported="false" />
...
</application>

5.配置混淆脚本

您编译APK前需要配置不要混淆小米游戏SDK,避免功能异常。
Android Studio开发环境里的配置文件是“proguard-rules.pro”,Eclipse开发环境里的配置文件是“proguard-project.txt”。

#小米SDK  
-keep class com.xiaomi.** {*;}
#gson
-keep class com.google.gson.** {*;}

4.3、检查是否为小米设备

调用checkIsXiaomi确认当前设备是否为小米设备,如果是小米设备,则使用小米游戏服务SDK完成联合登录

4.4、初始化

调用init接口完成游戏服务初始化,同时会对当前游戏进行校验,获取联合登录相关配置

4.5、联合登录

初始化成功后,游戏可调用unionLogin进行联合登录,游戏服务向玩家展示联合登录面板

  1. 支持配置联合登录弹窗的展示样式(图标or按钮)
  2. 支持切换账号场景,登录参数中changeAccount设置true即可
  3. 联合登录流程中,小米侧会对用户进行实名与防沉迷校验

4.6、关联游戏官方账号

关联游戏账号
玩家通过关联小米账号与游戏官方账号,可实现小米账号或游戏官方账号在小米设备上快速登录游戏,两种登录方式下游戏进度保持同步。因此,为了提升玩家登录体验,建议在游戏中提供关联游戏官方账号的功能。

  • 前提条件
    • 已调用初始化并返回正常。
    • 在小米开放平台配置支持关联登录
    • 在小米开放平台配置关联类型(手机号关联、非手机号关联、无手机号账号关联)
    • 在小米开放平台配置关联维度(开发者维度、游戏维度)

  • 开发步骤
  1. 通过unionLogin接口完成关联登录
  2. 调用unionLogin接口获取的isBinding值为true
  3. 游戏服务端基于回调参数中的
  4. 游戏服务端基于回调参数中的uid和gameId判断当前是否需要关联/创建新号/更新关联状态
    注意:关联状态以游戏服务端记录为准,每次登录后游戏服务端需要确认小米侧记录是否准确,如果不一致,再调用我们的bindAccount接口更新至最新
  5. 游戏侧完成关联后调用bindAccount接口通知小米侧



解除账号关联
为了考虑玩家体验,游戏需为玩家提供解除账号关联功能。接入步骤如下:

1.在游戏内为玩家提供一个解除关联按钮

建议按钮名称定位为“解除关联”、“关联解除”、“账号解绑”、“解绑按钮”、“解绑”等,避免和切换账号、退出登录、删除账号、注销账号等概念混淆。

2.玩家点击解除关联按钮时,建议游戏弹出窗口,提示用户确认解除账号关联行为

3.玩家点击窗口的解除关联确认按钮后,游戏需:

请求服务端的解除账号关联接口,或客户端接口

调用unBindAccount接口解除小米unionId与游戏官方账号gameId的关联关系。解除成功后,建议游戏退出到登录界面,并调用unionLogin接口重新拉起联合登录面板,允许玩家重新进行登录。

4.用户也可通过游戏中心的关联管理页面发起解除关联,小米会通过“解除账号关联通知”接口通知游戏侧

4.7、实名和防沉迷

所有登录场景,游戏服务都会对用户实名认证和未成年防沉迷。当用户选择游戏官方账号登录 或 小米账号关联登录时,游戏侧需要单独对用户进行实名认证和未成年防沉迷。

4.8、角色信息上报

玩家成功登录游戏并选择角色、区服后,游戏需要将角色信息提交到游戏服务

4.9、切换账号

游戏服务自动登录弹窗已为用户提供了切换账号入口,游戏可无需提供切换账号入口。
如游戏内部提供了切换账号入口,可调用unionLogin并传入强制展示登录弹窗的参数

4.10、客户端错误码

错误码错误码含义
10001当前未完成初始化
10003网络状态异常
10007参数错误
10008内部异常
10009登录频率限制
10010登录失败
10012AppId参数不合法
10013当前软件版本不支持
10022当前账号为空
10023当前账号不支持关联
10024用户未登录
-10003系统内部错误
10030角色上报失败
10031绑定失败
10032解绑失败

5、服务端接口

5.1、登录token校验&用户信息获取

功能介绍

  • 调用该接口,对已经获得的session进行鉴权。
  • 传入session到小米服务器上获取玩家的实名信息(是否实名、年龄、性别)和手机号等信息。

场景描述

游戏已经获取到session,要对其进行解析鉴权,通过session到小米服务器上获取玩家的实名信息(是否实名、年龄、性别)和手机号等信息。

接口原型

承载协议HTTPS POST
接口方向开发者服务器 -> 小米服务器
接口URLhttps://union-account-gu.s.migames.com/union-account/unbindAccount
数据格式请求:Content-Type: application/json
响应:Content-Type: application/js

请求参数

参数类型是否必选描述
uidStringY传入小米客户端返回的unionId
sessionStringYsession,12小时过期
appIdStringY应用ID
nonceStringY随机字符串
signatureStringY签名算法以AppSerectKey作为秘钥,signature本身不参与计算签名,详见5.4

请求示例

curl --request POST \
--url https://union-account-gu.s.migames.com/union-account/loginValidate \
--header 'Content-Type: application/json' \
--header 'User-Agent: insomnia/8.5.1' \
--data '{
"uid": "U2025060311000221",
"session": "B9G584msGAmGzozr",
"appId": "2882303761520416500",
"nonce": "ywb7dsllz4o1",
"signature": "71987ecb773356ed905ba63d0fce702d13015f43"
}'

响应参数

参数类型是否必选描述
retCodeintY业务返回码:200成功
errMsgStringY返回消息
dataStringN加密后的响应结果(使用serverSerectKey进行加解密)

data解密后字段

参数类型是否必选描述
realNameTypeintN用户实名标识
406 非身份证实名方式
407 实名认证通过,已成年
408 实名认证通过,未成年
409 未进行实名认证
ageintN用户年龄
isBellaintN性别:
1: 女性
0: 男性
nickNameStringN昵称
avatarUrlStringN头像
phoneNumStringN用户手机号
uidStringNuid
signatureStringN对data解密后的参数进行签名验证,签名算法以serverSerectKey作为秘钥,signature本身不参与计算签名

响应示例

{
"retCode":200,
"errMsg":"成功",
"data":"to+uiX2LC7usOEKNjmwYsFuOnOCU+CShGnMw+V2ds2KPLkyrIFMirF9y+uAxNbMZHGyYI
BmeXUgtCsDYQG4E4hj1/XPk/BXevG5IJfqMXtt0cYQe6Yyl3Ca9CCQRV3EP5qDduQaVPC
uEwSXrmfPfh6ZQWXd2JFrMRyOZrYJB32tsYqXB6PgL1HruIXJce8HN6MwLJoVbcPsN+NE
1SlN/kbbSFubQsGc7NOkNfPQc5ZUZbLAc8N38X/iV/AIjbW0lGDW2tDyMvYecOECGsXhx
whW87XkfWGO38jdyWr/q5m+PBF18Mbs9Ywb7Jd6Gku7Wd2gbuYF//w4CghkpYVFTcu/o2
0OL548I0hzrjMB3pyIDZPUO66IzevuLfKOTaHCUDv4OaZtnqdz5zgYg7WutnQ=="
}

*****data解密后********
{
"realNameType":407,
"age":33,
"isBella":1,
"nickName":"手机尾号91的小米账号",
"avatarUrl":"1.jpg",
"phoneNum":"12312312391",
"uid":"U2025060311000221",
"signature":"40d3352df588a2dd5cd45fcb3c464eb91ac9f89b"
}

data结果解密

加密/解密算法以AppSerectKey作为key,使用AesEcbBase64带密钥(secret)的算法对响应结果进行加密/解密。

java示例

/**
* aes加密(ECB)
*
* @param sSrc
* @param sKey
* @return
* @throws Exception
*/
public static String encryptAesEcbBase64(String sSrc, String sKey) {

try {
if (StringUtils.isBlank(sKey)) {
return null;
}
byte[] keyBytes = sKey.getBytes(StandardCharsets.UTF_8);
SecretKeySpec skeySpec = new SecretKeySpec(keyBytes, AES);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(sSrc.getBytes());
return (new Base64()).encodeToString(encrypted);
} catch (Exception e) {
log.error(e.getMessage(), e);
return null;
}
}

/**
* aes解密(ECB)
*
* @param sSrc
* @param sKey
* @return
*/
public static String decryptAesEcbBase64(String sSrc, String sKey) {
try {
if (StringUtils.isBlank(sKey)) {
return null;
}
byte[] raw = sKey.getBytes(StandardCharsets.UTF_8);
SecretKeySpec skeySpec = new SecretKeySpec(raw, AES);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] original = cipher.doFinal((new Base64()).decode(sSrc.getBytes()));
return new String(original);
} catch (Exception ex) {
log.error("decrypt err: " + ex.getMessage(), ex);
return null;
}
}

5.2、解除账号关联

功能介绍

调用此接口可以将游戏官方账号与小米openId的解绑结果上报给小米游戏服务器。

场景描述

玩家选择小米账号登录游戏时,游戏需要将游戏官方账号与小米openId绑定,并将绑定结果上报给小米游戏服务器。若需将游戏官方账号与小米openId解绑,需将解绑结果上报给小米,服务器侧则可通过本接口实现。

接口原型

承载协议HTTPS POST
接口方向开发者服务器 -> 小米服务器
接口URLhttps://union-account-gu.s.migames.com/union-account/unbindAccount
数据格式请求:Content-Type: application/json
响应:Content-Type: application/json

请求参数

参数类型是否必选描述
unionIdStringY联合登录场景会下发unionId
appIdStringY开发者站appId
fromStringY来源:
CP厂商:content_provider
nonceStringY随机字符串
signatureStringY签名算法以AppSerectKey作为秘钥,signature本身不参与计算签名,详见5.4

请求示例

curl --request POST \
--url https://union-account-gu.s.migames.com/union-account/unbindAccount \
--header 'Content-Type: application/json' \
--data '{
"unionId": "U2025060311000221",
"appId": "2882303761520416500",
"from": "content_provider",
"nonce": "md8s12kxsrnk",
"signature": "800ad5db2a35ed4273d09f8fe0469b9ba07cd693"
}'

响应参数

参数类型是否必选描述
retCodeintY业务返回码:200成功
errMsgStringY返回消息
dataStringN

响应示例

{
"retCode":200,
"errMsg":"成功",
"data":null
}

5.3、解除账号关联通知

功能介绍

小米游戏服务器调用此接口向开发者服务器发送关键事件通知,并提醒开发者解绑账号。

场景描述

在小米开发者站配置回调地址后,小米游戏服务器将在玩家解除小米账号关联后提醒开发者解绑账号。若开发者服务器返回结果为非成功响应,华为游戏服务器将周期性(3次)发送本次关键事件的通知,建议开发者服务端在收到通知后立即返回成功响应,避免堆积通知消息。

接口约束

  • 不允许开发者服务器设置IP允许清单用于限制小米侧的出口IP地址。IP允许清单本身并不能提高安全性且会给业务发展带来约束。因不遵守该约定而导致的后果将由游戏自行承担。
  • 必须提前在小米开发者站中配置开发者服务器的回调地址,地址要求必须支持HTTPS协议,且具有合法商用证书。

接口原型

承载协议HTTPS POST
接口方向小米服务器 -> 开发者服务器
最大响应时间< 1s
接口URL在小米开发者站中配置开发者服务器的回调地址URL
数据格式请求:Content-Type: application/json
响应:Content-Type: application/json

请求参数

参数类型是否必选描述
unionIdStringN联合登录场景会下发unionId
appIdStringY开发者站appId
nonceStringY随机字符串
signatureStringY签名算法以AppSerectKey作为秘钥,signature本身不参与计算签名,详见5.4

请求示例

curl --request POST \
--url {接口URL} \
--header 'Content-Type: application/json' \
--data '{
"unionId": "U2025060311000221",
"appId": "2882303761520416500",
"nonce": "md8s12kxsrnk",
"signature": "800ad5db2a35ed4273d09f8fe0469b9ba07cd693"
}'

响应参数

参数类型是否必选描述
retCodeintY业务返回码:200成功
errMsgStringY返回消息

响应示例

{
"retCode":200,
"errMsg":"成功"
}

5.4、签名生成与验证

验签机制

生成带签名字符串表中各参数按字母顺序排序(不包含signature),如果第一个字母相同,按第二个字母排序,依次类推。值为null的参数请不要参与签名
举例:排序后拼接成par1=val1&par2=val2&par3=val3的格式,所生成的字符串即为待签名的字符串。


签名算法以AppSerectKey作为key,使用hmac-sha1带密钥(secret)的哈希算法对待签字符串进行签名计算。

JAVA代码示例

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.util.Formatter;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;


public class HmacSha1Signature{

private static final String MAC_NAME = "HmacSHA1";
private static final String ENCODING = "UTF-8";
/**
* 使用 HMAC-SHA1 签名方法对对encryptText进行签名
*
* @param encryptText
* 被签名的字符串
* @param encryptKey
* 密钥
* @return 返回被加密后的字符串
* @throws Exception
*/
public static String hmacSHA1Encrypt(String encryptText, String encryptKey) throws Exception {
byte[] data = encryptKey.getBytes(ENCODING);
// 根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
SecretKey secretKey = new SecretKeySpec(data, MAC_NAME);
// 生成一个指定 Mac 算法 的 Mac 对象
Mac mac = Mac.getInstance(MAC_NAME);
// 用给定密钥初始化 Mac 对象
mac.init(secretKey);
byte[] text = encryptText.getBytes(ENCODING);
// 完成 Mac 操作
byte[] digest = mac.doFinal(text);
StringBuilder sBuilder = bytesToHexString(digest);
return sBuilder.toString();
}
/**
* 转换成Hex
*
* @param bytesArray
*/
public static StringBuilder bytesToHexString(byte[] bytesArray) {
if (bytesArray == null) {
return null;
}
StringBuilder sBuilder = new StringBuilder();
for (byte b : bytesArray) {
String hv = String.format("%02x", b);
// String hv = Integer.toHexString( b & 0xFF );
sBuilder.append(hv);
}
return sBuilder;
}

public static void main(String []args) throws Exception{
String hmac = hmacSHA1Encrypt("appId=2882303761520419939&nonce=PM3ENXm5canqCoCtC8fa4VYLVeSiySwF&session=G0jFAavU7ZsP00hN&uid=2025060707269734", "Secret_wrFNJJBsCNYSpXGBGGRYEKpItLldixAj");

System.out.println(hmac);
assert hmac.equals("ba80461b016c05a287d0471af1c8bd1335d1b812");
}
}
文档内容是否有帮助?
有帮助
无帮助