腾讯微博Android客户端开发——获取未授权的Request Token .
给大家介绍下腾讯微博API通过以下步骤来完成认证授权:
1.获取未授权的Request Token(temporary credentials)
2.请求用户授权Request Token
3.使用授权后的Request Token换取Access Token(token credentials)
本次给大家介绍如何获取未授权的Request Token。
在腾讯微博开放平台的API中介绍了获取Request Token的URL地址、所需要的参数以及返回内容。
获取request_token
URL:https://open.t.qq.com/cgi-bin/request_token
格式:xml,json
HTTPS请求方式:GET
是否需要鉴权:true
请求数限制:true
请求参数:
oauth_callback:回调URL 如果是桌面应用或手机应用没有回调URL,采用pin码方式,请填上 oauth_callback=null
oauth_consumer_key:你申请的appkey
oauth_nonce:随机串(32个字符长度)随机生成,只能使一次,与时间戳一起 防重放
oauth_signature:oauth请求签名 oauth请求的签名,根据oauth协议中算法生成basestring 后,用appsecret 对basestring 经hmac_sha1生成的签名串
oauth_signature_method:签名方法(HMAC-SHA1)
oauth_timestamp:时间戳 你的请求当前时间戳 (你的服务器时间你定要准确,不然请求会被拒绝掉)
oauth_version:oauth版本号(填 1.0 )
使用示例如下:
返回结果:
oauth_token=a63f4a0e1242462fb8c11e53159ba294&oauth_token_secret=40ece707e064128e4fec692e3c09c692&oauth_callback_confirmed=true
返回结果说明:
oauth_token:返回的request_token
oauth_token_secret:返回的request_secret
oauth_callback_confirmed:回调确认
使用流程图表示则十分的简单:
其中URL地址和请求方式我们已经可以直接指定:
view plaincopy to clipboardprint?
String url = "https://open.t.qq.com/cgi-bin/request_token";
String httpMethod = "GET";
请求所需的参数除了oauth_signature外我们都可以直接指定或者调用前面将结果的方法:
List params = new ArrayList();
String timestamp = generateTimeStamp();
String nonce = generateNonce(false);
params.add(new Parameter("oauth_consumer_key", CONSUMER_KEY));
params.add(new Parameter("oauth_signature_method", SIGNATURE_METHOD));
params.add(new Parameter("oauth_timestamp", timestamp));
params.add(new Parameter("oauth_nonce", nonce));
params.add(new Parameter("oauth_callback", "null"));
params.add(new Parameter("oauth_version", "1.0"));
同时发送请求和处理返回信息的方法在前面已给大家介绍,我们也可直接调用:
try
{
SyncHttp http = new SyncHttp();
String result = http.httpGet(url, params);
} catch (Exception e)
{
e.printStackTrace();
}
下面我们所需要处理的就是得到oauth_signature的值。
通过阅读帮助文档我们可得知oauth_signature是将请求源串以及密钥根据一定签名方法生成的签名值,用来提高传输过程参数的防篡改性。
签名值的生成共有3个步骤:构造源串,构造密钥,生成签名值。
Step 1.构造源串
第1步:将请求的URI路径进行URL编码。
第2步:将除“oauth_signature”外的所有参数按key进行字典升序排列。
第3步:将第2步中排序后的参数(key=value)用&拼接起来,并进行URL编码。
第4步:将HTTP请求方式(GET或者POST)以及第1步和第3步中的字符串用&拼接起来。
Step 2. 构造密钥
密钥由2部分内容用“&”拼接起来:
oauth_consumer_secret & oauth_token_secret
Step 3. 生成签名值
1. 使用HMAC-SHA1加密算法,将Step1中的到的源串以及Step2中得到的密钥进行加密。
2. 然后将加密后的字符串经过Base64编码,即得到oauth_signature签名参数的值。
代码如下:
String tokenSecret = "";
// App Key
String consumer_key = "dabd7b3bdf744acc9777a506c74c285e";
// App Secret
String consumer_secret = "04fb0ca42cb64ab06ef606b49579c9cb";
// 签名方法
String signature_method = "HMAC-SHA1";
// 请求URL
String url = "https://open.t.qq.com/cgi-bin/request_token";
// 请求方式
String httpMethod = "GET";
// 保存参数集合
List<Parameter> params = new ArrayList<Parameter>();
// 得到时间戳
String timestamp = generateTimeStamp();
// 单次值
String nonce = generateNonce();
// 添加参数
params.add(new Parameter("oauth_consumer_key", consumer_key));
params.add(new Parameter("oauth_signature_method", signature_method));
params.add(new Parameter("oauth_timestamp", timestamp));
params.add(new Parameter("oauth_nonce", nonce));
params.add(new Parameter("oauth_callback", "null"));
params.add(new Parameter("oauth_version", "1.0"));
// Step 1.构造源串:HTTP请求方式 & urlencode(uri) & urlencode(a=x&b=y&...)
StringBuilder baseStringBuilder = new StringBuilder();
baseStringBuilder.append(httpMethod);
baseStringBuilder.append("&");
baseStringBuilder.append(encode(url));
baseStringBuilder.append("&");
// 所有参数按key进行字典升序排列
Collections.sort(params);
for (Parameter param : params)
{
String name = encode(param.getName());
String value = encode(param.getValue());
baseStringBuilder.append(name);
baseStringBuilder.append("%3D"); // 字符 =
baseStringBuilder.append(value);
baseStringBuilder.append("%26"); // 字符 &
}
// 删除末尾的%26
baseStringBuilder.delete(baseStringBuilder.length() - 3, baseStringBuilder.length());
String baseString = baseStringBuilder.toString();
// Step 2. 构造密钥
String oauthKey = "";
if (null == tokenSecret || tokenSecret.equals(""))
{
oauthKey = encode(consumer_secret) + "&";
} else
{
oauthKey = encode(consumer_secret) + "&" + encode(tokenSecret);
}
// 生成签名值
byte[] encryptBytes = HMAC_SHA1.HmacSHA1Encrypt(baseString, oauthKey);
String signature = Base64.encode(encryptBytes);
params.add(new Parameter("oauth_signature", signature));
// 构造传递参数字符串
StringBuilder urlBuilder = new StringBuilder();
for (Parameter param : params)
{
urlBuilder.append(param.getName());
urlBuilder.append("=");
urlBuilder.append(param.getValue());
urlBuilder.append("&");
}
urlBuilder.deleteCharAt(urlBuilder.length() - 1);
String urlParams = urlBuilder.toString();
SyncHttp http = new SyncHttp();
String result = http.httpGet(url, urlParams);
System.out.println(result);
通过上面代码我们就能获取平台传递过来的信息,当然代码显得比较臃肿,课中中会分割在几个方法中。正常的返回结果为:
oauth_token=079ad6989409456a9878bf41ca8d2d7a&oauth_token_secret=b494075906b8846416735bf802ced89f&oauth_callback_confirmed=true
我们可以编写一个辅助方法获取每个返回参数的值,已供以后使用:
/**
* 分割返回结果
*
* @param response
* 返回字符串
* @return
*/
public static Map<String, String> splitResponse(String response)
{
// 保存返回结果
Map<String, String> map = new HashMap<String, String>();
// 判断是否为空
if (!TextUtil.isEmpty(response))
{
// 已“&”进行分割
String[] array = response.split("&");
if (array.length > 2)
{
String tokenStr = array[0]; // oauth_token=xxxxx
String secretStr = array[1];// oauth_token_secret=xxxxxxx
String[] token = tokenStr.split("=");
if (token.length == 2)
{
map.put("oauth_token", token[1]);
}
String[] secret = secretStr.split("=");
if (secret.length == 2)
{
map.put("oauth_token_secret", secret[1]);
}
}
}
return map;
}