小米帐号OAuth 2.0互通接口应用学习
来源:互联网 发布:linux安装gcc 编辑:程序博客网 时间:2024/04/29 18:11
最近,在做一个和小米账号互通的第三方登陆接口,详细的学习了小米开发者文档,下面对接口文档的学习进行总结和汇总。
1.相关名词的解释
- 服务提供方(resource server): 用户使用服务提供方来存储受保护的资源,这里指的是小米公司。
- 用户(user):存放在服务提供方的受保护的资源的拥有者。
- 客户端(client):要访问服务提供方资源的第三方应用,通常是网站在认证过程之前,客户端要向服务提供者申请客户端标识。
- 令牌(token):分发给客户端的代表访问授权的字符串。通常这个字符串对客户端来说是不透明的。令牌代表资源拥有者许可的访问作用域和持续时间,并由资源服务器和授权服务器强制保证。这个令牌可以代表一个标识符,用于检索授权信息,或以一种可验证的方式自包含授权信息(即一个包含数据和签名的令牌字符串)。令牌可能只代表纯粹的访问能力。
- 访问令牌(access token):客户端用来代表资源拥有者发送验证请求的令牌。 小米API将支持OAuth 2.0中Bearer Token和MAC Token的两种token形式。
- 刷新令牌(refresh token):客户端用来获取新的访问令牌的令牌,而不用资源拥有者的参与。
- 授权码(code):一个短期令牌,代表终端用户的授权。授权码用于获取一个访问令牌和一个刷新令牌。
- 客户端标识符(client id):分发给客户端的唯一标识,用于客户端向授权服务器标识自己。客户端标识符可以有一个对应的密钥。
2.授权接口说明
授权码方式(authorization code)获取访问令牌(access token)的授权验证流程又被称为web server flow,适用于所有有服务端的应用,如Web/Wap站点、有服务端的手机/桌面客户端应用等。
2.1请求用户授权接口
- URL: https://account.xiaomi.com/oauth2/authorize
- HTTP请求方: GET
请求用户授权参数表
接口返回值
response_type为code(Authorization Code Flow)时接口返回值:
2.2 获取访问令牌接口
- URL : http://account.xiaomi.com/oauth2/token
- HTTP请求方式: GET
获取访问令牌参数表
接口返回值
接口返回值是一个Json格式字符串,具体说明如下:
第三方获取访问令牌验证通过,该接口返回Access Token相关的信息:
{
“access_token”: “access token value”,
“expires_in”: 360000,
“refresh_token”: “refresh token value”,
“scope”: “scope value”,
“token_type “: “mac”,
“mac_key “: “mac key value”,
“mac_algorithm”: ” HmacSha1”
“openId”=”2.0XXXXXXXXX”
}
字段说明:
1. access_token:获取的Access Token;
2. expires_in:Access Token的有效期,以秒为单位;
3. refresh_token:用于刷新Access Token ,有效时间为10年;
4. scope:Access Token最终的访问范围,既用户实际授予的权限列表;
5. token_type: access token的类型,type值为mac;
6. mac_key: MAC加密算法对请求进行加密时的密钥;
7. mac_algorithm:MAC加密的算法,目前只支持HmacSha1
8. openId: 是v2版本所提供的一种唯一标识
2.3获取用户名片
- URL: https://open.account.xiaomi.com/user/profile
- HTTP请求方式:GET
获取用户名片参数表
返回数据
- 正确返回:
如果访问令牌验证通过,会返回用户相关的信息, 返回格式为Json文本, 格式如下:
{
“result”: “ok”,
“description”: “成功”,
“data”: {
“miliaoNick”: “米聊昵称”,
“userId”: 米聊号,
“miliaoIcon”: 头像URL
},
“code”: 0
} - 错误返回
如果访问令牌验证错误,会返回错误信息, 返回格式为Json文本, 格式如下:
{
“result”: “error”,
“description”: “错误描述”,
“code”: 错误码
}
3.Mac Token详细说明
MacToken是授权小米下发的一种访问令牌类型,使用MacToken调用API时,用MAC加密算法对请求进行加密,并将结果放到http请求的header中。MAC算法有HmacSha1和HmacSha256两种,小米API默认使用HmacSha1。
Java算法示例
public static byte[] encryptHMACSha1(byte[] data, byte[] key) { SecretKeySpec signingKey = new SecretKeySpec(key, HMAC_SHA1); Mac mac = Mac.getInstance(HMAC_SHA1); mac.init(signingKey); mac.update(data); return mac.doFinal();}
PHP算法示例
static public function buildSignature($signString, $secret) { $sign = base64_encode(hash_hmac('sha1', $signString, $secret, True)); return urlencode($sign);}
3.1请求内容标准化
使用Mac Token需要将请求内容按照一定的规则拼接形成符合要求的标准的格式字符串,标准化字符串用于计算请求API的签名值,小米规定的格式请求字符串格式如下(\n代表换行):
格式化字符串 = Nonce + \n + HTTP方法 + \n + HOST + \n + URI+ \n + QUERY+\n
具体示例:
请求字符串=54897465748976549:21459478\nGET\n open.account.xiaomi.com\n/user/profile\n
clientId=xxx&token=xxx\n
3.2MacToken请求格式
采用Mac Token调用API,需要将相关签名信息放入请求的http请求的Header中。第三方在发送API请求时,要对请求进行MAC加密计算,并将结果放到请求Header中的”Authorization”字段中。
Authorization字段内容如下:
Authorization: MAC access_token=”token value”,nonce=”随机码” ,mac=”签名值”
字段含义说明:
1. access_token : 授权时下发的access_token。
2. nonce:随机串,由客户端按照2中规则产生的随机字符串包括当前分钟数值。
3. mac:签名值,根据mac算法计算生成的。Mac = HmacSha1(格式化字符串, mac_key)。
相关方法的源代码
static long localTimeDiff = dateDiff(DateTime.Now, getServerTime());static private Random ran = new Random(Dns.GetHostName().GetHashCode()+ (int)DateTime.Now.Ticks);//根据主机名的hashcode和现在时间得到随即种子;/** * 获取时间差(注意时区) * @param DateTimeStart时间开始 * @param DateTimeEnd时间结束 * @return 得到时差 */static long dateDiff(DateTime DateTimeStart, DateTime DateTimeEnd){ long dateDiff = 0; TimeSpan end = new TimeSpan(DateTimeEnd.Ticks); TimeSpan start = new TimeSpan(DateTimeStart.Ticks); TimeSpan diff = end.Subtract(start).Duration(); dateDiff = (diff.Days * 24 + diff.Hours); dateDiff = dateDiff * 60 + diff.Minutes; Console.WriteLine("get the timediff " + dateDiff); return dateDiff;}/** * 得到header的值 * @param nonce为随机数 * @param mac为mac加密的值 * @param accessToken为访问令牌 * @return 得到header的值 */static public String createHeader(string nonce, string mac, string accessToken){ string header = string.Format("MAC access_token=\"{0}\",nonce=\"{1}\",mac=\"{2}\"", Uri.EscapeDataString(accessToken), Uri.EscapeDataString(nonce), Uri.EscapeDataString(mac)); return header;}/** * 得到HMACSHA1加密的密文(密文格式为nonce + \n + method(POST\GET) + \n + host + \n + uriPaht + \n + req(queryparam按照key的字典序)+\n(最后也需要添加一个\n)) * @param nonce为随机数 * @param query为请求 * @param method http方法,填“GET”或“POST” * @param localPath使用参数详情看sdk文档 * @param macKey,hmacsha1的密钥 * @return 得到HMACSHA1加密的密文 */static public String createCiphertext(string nonce, string query, string method, string localPath, string macKey){ method = method.ToUpperInvariant(); string ciphertext = nonce + "\n" + method + "\n" + XiaoMiHttpClientConst.hostURI + "\n" + localPath + "\n" + query + "\n"; HMACSHA1 hmacsha1 = new HMACSHA1(); hmacsha1.Key = Encoding.UTF8.GetBytes(macKey); byte[] dataBuffer = Encoding.UTF8.GetBytes(ciphertext); byte[] hashBytes = hmacsha1.ComputeHash(dataBuffer); ciphertext = Convert.ToBase64String(hashBytes); return ciphertext;}/*** 得到服务器现在的时间* @param * @return 得到服务器现在的时间*/static public DateTime getServerTime(){ HttpWebRequest request = (HttpWebRequest)WebRequest.Create(XiaoMiHttpClientConst.apiURI); request.Method = "GET"; HttpWebResponse response; Console.WriteLine("waiting for getting the server time"); try { response = (HttpWebResponse)request.GetResponse(); } catch (WebException ex) { response = (HttpWebResponse)ex.Response; } if (response == null) Console.WriteLine("error: can not get the server time ,please check the network connections"); return response.LastModified;}/* * 得到Nonce用 随机数:时间分钟差 为格式 * @param * @return Nonce */static public string getNonce(){ //产生随机数过程 int randKey = ran.Next(); string nonce = randKey + ":" + (dateDiff(new DateTime(1970, 1, 1, 8, 0, 0), DateTime.Now) + localTimeDiff); return nonce;}
- 小米帐号OAuth 2.0互通接口应用学习
- OAuth学习
- oauth学习
- 【OAuth】理解OAuth 2.0
- OAuth 2.0协议原理学习汇总
- 新浪微博OAuth 2.0接口简单实例例
- 阿里巴巴与淘宝网今日起帐号实现互通
- 用Python(Tornado)模拟登录小米帐号
- Android应用互通的实现
- oauth 2.0
- OAuth 2.0
- OAuth 2.0
- OAuth 2.0
- OAuth 2.0
- OAuth 2.0
- OAuth 2.0
- OAuth 2.0
- OAuth 2.0
- SVN服务器搭建和使用
- zoj2193_Window Pains
- 库房数据表
- 数据库连不上一般处理办法
- tmp
- 小米帐号OAuth 2.0互通接口应用学习
- Linux基础一
- UICollectionView详解五:瀑布流
- 【ThinkingInJava】59、执行线程的时候我们可以设定相应的优先级
- MyEclipse 配置 ExtJS
- java实现二维码扫描登录
- 开源杂谈
- 并发编程概念篇
- 要么形成生态,要么加入生态?