一、API MAC 签名算法
小米开放平台一些 API 需要进行 MA C验证, 在调用 API 时用 MAC 加密算法对请求进行加密,并将结果放到请求的 header 中。
1、MAC计算
- 请求内容标准化
标准化的请求字符串,就是用指定的请求属性按照某个规则拼接而成的字符串。在这里,其实标准化请求字符串,就是将 nonce,HTTP METHOD,HOST,URI,QUERY 以换行符(即:\n
)为连接符,合并起来得到的字符串(格式串结尾增加\n),其中涉及到属性:
属性 | 说明 | 示例 |
nonce | 由随机数和时间戳组成,格式:随机数:当前分钟数 | 54897465748976549:21459478(注意冒号分割) |
HTTP METHOD | 调用 API 时请求方式 | GET/ POST (大写) |
HOST | 调用 API 时的 host | 例如: open.account.xiaomi.com (没有 http 或 https) |
URI | 调用 API 时的 path (必须以 / 开头) | 例如: /user/profile |
QUERY | 请求参数名称按照字典序排列的 query 串, 内容为空的 query 字段不参与签名 | clientId=xxx&token=xxx |
- 标准化示例
54897465748976549:21459478\nGET\nopen.account.xiaomi.com\n/user/profile\nclientId=xxx&token=xxx\n
注意:上述换行符“\n”仅用于展示
- MAC 计算
客户端使用 MAC 算法和 MAC 密钥来对“标准化的请求字符串”进行加密计算出消息认证码,MAC算法有 hmac-sha-1 和 hmac-sha-256 两种,我们目前只支持hmac-sha-1。
mac = HMAC-SHA1(mac_key, 标准化的请求字符串)
MAC 计算示例,以请求用户基本信息 API为例说明:
请求地址: https://open.account.xiaomi.com/user/profile
请求参数:
clientId=179887661252608&token=eJxjYGAQydknLLCFsVyIR-DxSqdTnQFGfX4yDAwMjAzxQJIheJfnRTDtvAhMM8SE_2FgWDw7Rg3MYzdUMFIwVjABMplzE5MBClYRuw
nonce: 2870867952176701445:23282360
HTTP方法: GET
拼接得到标准化字符串:
2870867952176701445:23282360\nGET\nopen.account.xiamomi.com\n/user/profile\nclientId=179887661252608&token=eJxjYGAQydknLLCFsVyIR-DxSqdTnQFGfX4yDAwMjAzxQJIheJfnRTDtvAhMM8SE_2FgWDw7Rg3MYzdUMFIwVjABMplzE5MBClYRuw\n
Mac Key:
ORhx44qK6Alqf8vt2rGB5f-oPq0
签名结果输出(已Base64编码):
9uvros2WcjMaJ3pH25eQZU9p5pA=
2、MAC 请求格式
- Header 格式说明
采用 MAC 签名验证调用 API,需要将相关签名信息放入请求的 HTTP 请求的 header 中,第三方在发送 API 请求时需要在请求 header 中添加 Authorization 字段。Authorization字段内容如下:
Authorization: MAC access_token="token value",nonce="随机码" ,mac="签名值"
- 字段说明:
access_token : 授权时下发的访问令牌
nonce: 随机串,计算 mac 时候使用的 nonce
mac: 按照上面的方法计算得到的结果(例如:9uvros2WcjMaJ3pH25eQZU9p5pA=)
二、_xmSign 签名算法
验证用户密码接口中的 _xmSign
字段基于 API MAC 签名算法生成,两者的区别在于 MAC 签名计算签名的时候使用的是 mac_key,_xmSign
计算用的是 client_secret。
_xmSign= HmacSha1(client_secret, callback 标准化字符串)
其中 _xmNonce
和 _xmSign
不参与标准化。
_xmSign签名验证示例:
第三方提供的Callback: http://third_url.com/xm
小米验证成功之后调用的 callback:
http://third_url.com/xm?xmResult=true&xmUserId=1909031&code=93D6A6663C1095587F68281E654D5526&_xmNonce=5964262989045079397%3A24012419&_xmSign=m%2FM1Ia6fOBfKWUbae5G5UXnqh5I%3D
其中_xmNonce=5964262989045079397:24012419, _xmSign=m/M1Ia6fOBfKWUbae5G5UXnqh5I=
参数:
xmResult=true&xmUserId=1909031&code=93D6A6663C1095587F68281E654D5526(_xmNonce和_xmSign不参与标准化)
nonce: 5964262989045079397:24012419
HTTP方法: GET
拼接得到的标准化字符串:
5964262989045079397:24012419\nGET\nxiaomi.com\n/\n&code=93D6A6663C1095587F68281E654D5526&xmUserId=1909031&xmResult=true\n
client secret:
ORhx44qK6Alqf8vt2rGB5f-oPq0
签名结果输出(已Base64编码):
m/M1Ia6fOBfKWUbae5G5UXnqh5I=