的Twitter的Oauth失败,原因是签名和令牌
我想箱子一个应用程序从Twitter进行身份验证,但我得到以下错误 :的Twitter的Oauth失败,原因是签名和令牌
Failed to validate oauth signature and token
这里是我的应用程序代码:
public class TwitCons {
String sign_method ="HMAC-SHA1";
public static String consumer_key ="^^^^^^^^^^^^^^^^^^^^";
public static String consumer_secret="^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^";
String request_uri = "https://api.twitter.com/oauth/request_token";
String oauth_callback="http://127.0.0.1:8080/twitter/getToken";
String getNonce(){
Random ran = new Random();
long nonce1 = ran.nextLong();
Long nonce = Math.abs(new Long(nonce1));
return nonce.toString();
}
String getTimestamp(){
long time = System.currentTimeMillis();
return String.valueOf(time/1000);
}
String getSignature(String request_uri ,String request_token,String nonce) throws UnsupportedEncodingException
{
String base="oauth_callback=http://127.0.0.1:8080/twitter/getToken&oauth_consumer_key="+consumer_key+"&oauth_nonce="+nonce+"&oauth_signature_method="+sign_method+"&oauth_timestamp="+getTimestamp()+"&oauth_token=&oauth_version=1.0";
String baseString="POST&"+URLEncoder.encode(request_uri , "UTF-8")+"&"+URLEncoder.encode(base , "UTF-8");
String signKey = consumer_secret +"&"+ request_token ;
System.out.println(signKey +"\n"+baseString);
try {
SecretKeySpec signingKey = new SecretKeySpec(signKey.getBytes(),"HmacSHA1");
Mac mac = Mac.getInstance(signingKey.getAlgorithm());
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(baseString.getBytes());
String result = new String(Base64.encodeBase64(rawHmac));
System.out.println(URLEncoder.encode(result , "UTF-8"));
return URLEncoder.encode(result , "UTF-8");
//return result;
} catch (GeneralSecurityException e) {
return "";
}
}
}
和
public class Twitter extends TwitCons{
public void getRequest() throws IllegalArgumentException, HttpException, IOException
{
HttpClient client = new HttpClient();
PostMethod post = new PostMethod("https://api.twitter.com/oauth/request_token");
String nonce=getNonce();
String header = "oauth_callback=\""+URLEncoder.encode(oauth_callback ,"UTF-8")+"\","+
"oauth_consumer_key=\""+consumer_key +"\","+
"oauth_nonce=\""+nonce + "\","+
"oauth_signature=\""+getSignature(request_uri,"",nonce) + "\","+
"oauth_signature_method=\""+sign_method + "\","+
"oauth_timestamp=\""+getTimestamp() + "\","+
"oauth_version=\"1.0\"" ;
post.addRequestHeader("Authorization", "OAuth "+header);
client.executeMethod(post);
System.out.println(post.getResponseBodyAsString()+"\n"+post.getRequestHeader("Authorization"));
}
类有方法getRequest用于使twitte在r要求越来越request_token和token_secret
和第二类TwitCons有不同的方法和常量来获得请求令牌
你缺少
oauth_token
在
String base
。见
https://dev.twitter.com/docs/auth/3-legged-authorization如何获得一个(如果你还不知道这一点,并没有忘记把它放在你的基本字符串;))。
可能是因为您的base
字符串中包含&oauth_token=
而导致您的签名计算错误,但该密钥不属于您的请求的一部分。 OAuth 1.0 specification只是说:
签名基本字符串是请求元素一致的可重复串联到单个字符串中。
可能值得尝试去除那部分字符串。
UPDATE:
你可能有来urlencode在Authorization头回调URL,有字母排序,并把参数引号为@空气-DEX建议。试试这个:
String oauth_callback = "http://127.0.0.1:8080/twitter/getToken";
String oauth_callback_encoded = URLEncoder.encode(oauth_callback, "UTF-8");
然后
String header = "oauth_callback=\"" + oauth_callback_encoded + "\", " +
"oauth_consumer_key=\"" + consumer_key + "\", " +
"oauth_nonce=\"" + nonce + "\", " +
"oauth_signature=\"" + getSignature(request_uri, "", nonce) + "\", " +
"oauth_signature_method=\"" + sign_method + "\", " +
"oauth_timestamp=\"" + getTimestamp() + "\", " +
"oauth_version=\"1.0\"";
和
String base = "oauth_consumer_key=" + consumer_key +
"&oauth_nonce=" + nonce +
"&oauth_signature_method=" + sign_method +
"&oauth_timestamp=" + getTimestamp() +
"&oauth_version=1.0";
在Twitter.getRequest()
,似乎你的头看起来是错误的。各参数的值必须由双引号,包围("
):https://dev.twitter.com/docs/auth/authorizing-request
EDIT:
StringBuilder headerBuilder = new StringBuilder("OAuth ");
headerBuilder.append("oauth_callback=\"").append(oauth_callback).append("\", ");
headerBuilder.append("oauth_consumer_key=\"").append(consumer_key).append("\", ");
headerBuilder.append("oauth_nonce=\"").append(nonce).append("\", ");
headerBuilder.append("oauth_signature=\"").append(getSignature(request_uri,"",nonce)).append("\", ");
headerBuilder.append("oauth_signature_method=\"").append(sign_method).append("\", ");
headerBuilder.append("oauth_timestamp=\"").append(getTimestamp()).append("\", ");
headerBuilder.append("oauth_version=\"1.0\"");
String header = headerBuilder.toString();
更多细节请参见Twitter API中的相应的页面代码固定,因为没有逗号前的空格。
我有chnages的代码,并添加了“...正如你所说..但仍然没有工作 – behinddwalls 2012-07-10 06:47:33
在阅读如何使头再次,在逗号前没有空格,这是我的我编辑了代码。 – 2012-07-10 16:15:15
错误。所有经过验证的请求都需要'oauth_token',而'POST https:// api.twitter.com/oauth/request_token'则需要'oauth_token'。这是合乎逻辑的,因为您要求提供OAuth令牌。 ;-) – 2012-07-08 18:08:45
该死的,我把它与OAuth2流,您首先重定向用户,然后请求访问令牌;)我将更新与另一个建议的帖子... – 2012-07-08 18:30:40
我已经尝试了所有这些事情,但仍然得到同样的错误又一次... – behinddwalls 2012-07-09 10:58:10