小米无官方PHP SDK,需手动实现OAuth2流程:跳转授权→换取access_token→调用/user/profile接口;注意redirect_uri严格一致、表单编码、Bearer认证及state校验。

小米开放平台 PHP SDK 没官方维护,别直接 composer require
小米目前不提供官方 PHP SDK,网上搜到的所谓“小米 SDK”多是第三方非维护项目,composer require xiaomi/openapi 这类包基本已失效或无法对接当前 OAuth2 流程。硬套旧版 SDK 会导致 invalid_client 或 unsupported_grant_type 错误。
正确做法是:手动实现 OAuth2 授权码流程 + 直接调用 REST API。核心就三步:跳转授权 → 换取 access_token → 请求用户信息。
- 必须使用 HTTPS 回调域名,且需在小米开放平台后台「应用设置」中精确填写(含端口、路径,不能带 www 或 http://)
- scope 必须包含
user.profile.read,否则/user/profile接口返回 403 - 小米不支持 PKCE,但要求
redirect_uri在请求授权和换取 token 时**完全一致**(字符级相同)
获取 access_token 时 POST 参数必须用 application/x-www-form-urlencoded
小米的 /oauth2/token 接口只认表单编码,用 JSON 或 raw body 会返回 {"error":"unsupported_grant_type"}。PHP 里最容易错的是用 json_encode() 发送或漏设 Content-Type 头。
示例关键代码:
立即学习“PHP免费学习笔记(深入)”;
$data = http_build_query([
'client_id' => 'your_client_id',
'client_secret' => 'your_client_secret',
'grant_type' => 'authorization_code',
'redirect_uri' => 'https://yourdomain.com/callback.php',
'code' => $_GET['code']
]);
$ch = curl_init('https://account.xiaomi.com/oauth2/token');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/x-www-form-urlencoded']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
- 不要在
client_secret前加Basic,小米不走 Basic Auth -
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false)仅限测试,上线必须保留证书验证 - 响应是 JSON 字符串,记得
json_decode($response, true),字段名是access_token(不是accessToken)
调用 /user/profile 接口必须带 Authorization Bearer 头
拿到 access_token 后,请求用户基本信息要用 GET https://account.xiaomi.com/user/profile,且必须带 Authorization: Bearer xxx 头。漏掉头、写成 Bearer: xxx 或拼错单词都会返回 401。
常见错误响应:
-
{"error":"invalid_token"}→ token 过期或签名无效(检查是否被 URL 解码过) -
{"error":"insufficient_scope"}→ 授权时没申请user.profile.readscope - 空响应或 500 → 小米服务端偶尔不稳定,重试即可,不用改代码
请求示例:
$ch = curl_init('https://account.xiaomi.com/user/profile');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $access_token,
'Accept: application/json'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$userData = json_decode(curl_exec($ch), true);
// $userData['userId'] 是小米账号唯一 ID,不是手机号
小米用户 ID 和 UnionID 机制容易混淆
小米没有类似微信的 UnionID 概念。同一个小米账号在不同应用里返回的 userId 是相同的,但 openId(如果接口返回)是应用级的,且小米文档里基本不提 openId —— 实际上当前 /user/profile 接口只返回 userId、displayName、avatarUrl 等基础字段。
- 别指望通过接口拿到手机号或邮箱,小米默认不授权,需单独申请权限并审核
-
userId是数字字符串(如"123456789"),注意 PHP 中别用整型比较,避免溢出或精度丢失 - 小米账号体系里,“小米账号”和“小米生态账号”是同一套,不存在跨体系映射问题
最常被忽略的一点:小米 OAuth 的 state 参数必须你自己生成、校验并存储(比如存在 session 或 redis),否则 CSRF 风险真实存在,而且小米不会帮你做 state 绑定校验。



















