[英]Getting “Unauthorized” Error while trying to get Oauth request_token from twitter API
I am trying to get Oauth request_token from twitter API. 我正在尝试从Twitter API获取Oauth request_token。 But when I am running the code, it is giving output "Unauthorized", though I am an authorized user. 但是,当我运行代码时,尽管我是授权用户,但输出为“未经授权”。 Following is the output : 以下是输出:
"parameter_string=oauth_consumer_key=MlyUxiF1ihXIymYIPWZCA&oauth_nonce=7ee1983904884d45b723f6cc50306617&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1385127328&oauth_version=1.0
signature_base_string=POST&https%3A%2F%2Fapi.twitter.com%2Foauth%2Frequest_token&oauth_consumer_key%3DMlyUxiF1ihXIymYIPWZCA%26oauth_nonce%3D7ee1983904884d45b723f6cc50306617%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1385127328%26oauth_version%3D1.0
oauth_signature=%2FOnHRfoRKyxPd9KG%2BA0HlFvE6yg%3D
authorization_header_string=OAuth oauth_consumer_key="MlyUxiF1ihXIymYIPWZCA",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1385127328",oauth_nonce="7ee1983904884d45b723f6cc50306617",oauth_version="1.0",oauth_signature="%2FOnHRfoRKyxPd9KG%2BA0HlFvE6yg%3D"
log4j:WARN No appenders could be found for logger (org.apache.http.impl.conn.BasicClientConnectionManager).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Unauthorized
"
And here is my full code: 这是我的完整代码:
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.GeneralSecurityException;
import java.util.Date;
import java.util.UUID;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
public class TwitterConnection {
public static void main(String args[]) throws UnsupportedEncodingException {
// System.out.println(System.getProperty("java.classpath"));
String oauth_signature_method = "HMAC-SHA1";
String oauth_consumer_key = "MlyUxiF1ihXIymYIPWZCA";
String uuid_string = UUID.randomUUID().toString();
uuid_string = uuid_string.replaceAll("-", "");
String oauth_nonce = uuid_string; // any relatively random alphanumeric
// string will work here. I used
// UUID minus "-" signs
long timestamp_at_entry = new Date().getTime();
String oauth_timestamp = (new Long(timestamp_at_entry / 1000))
.toString(); // get current time in milliseconds, then divide by
// 1000 to get seconds
// I'm not using a callback value. Otherwise, you'd need to include it
// in the parameter string like the example above
// the parameter string must be in alphabetical order
String parameter_string = "oauth_consumer_key=" + oauth_consumer_key
+ "&oauth_nonce=" + oauth_nonce + "&oauth_signature_method="
+ oauth_signature_method + "&oauth_timestamp="
+ oauth_timestamp + "&oauth_version=1.0";
System.out.println("parameter_string=" + parameter_string);
String signature_base_string = "POST&https%3A%2F%2Fapi.twitter.com%2Foauth%2Frequest_token&"
+ URLEncoder.encode(parameter_string, "UTF-8");
System.out.println("signature_base_string=" + signature_base_string);
String oauth_signature = "";
try {
oauth_signature = computeSignature(signature_base_string,
"122595245-sPcfsJO3GRkJpjzgFLZ918OaHkxeSmwYg9WDn23Z"); // note
// the
// &
// at
// the
// end.
// Normally
// the
// user
// access_token
// would
// go
// here,
// but
// we
// don't
// know
// it
// yet
// for
// request_token
System.out.println("oauth_signature="
+ URLEncoder.encode(oauth_signature, "UTF-8"));
} catch (GeneralSecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String authorization_header_string = "OAuth oauth_consumer_key=\""
+ oauth_consumer_key
+ "\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"" +
oauth_timestamp + "\",oauth_nonce=\"" + oauth_nonce
+ "\",oauth_version=\"1.0\",oauth_signature=\""
+ URLEncoder.encode(oauth_signature, "UTF-8") + "\"";
System.out.println("authorization_header_string="
+ authorization_header_string);
String oauth_token = "";
HttpClient httpclient = new DefaultHttpClient();
try {
// HttpParams params = new SyncBasicHttpParams();
// HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
// HttpProtocolParams.setContentCharset(params, "UTF-8");
// HttpProtocolParams.setUserAgent(params, "HttpCore/1.1");
// HttpProtocolParams.setUseExpectContinue(params, false);
//
// HttpProcessor httpproc = new ImmutableHttpProcessor(
// new HttpRequestInterceptor[] {
// // Required protocol interceptors
// new RequestContent(), new RequestTargetHost(),
// // Recommended protocol interceptors
// new RequestConnControl(), new RequestUserAgent(),
// new RequestExpectContinue() });
//
// HttpRequestExecutor httpexecutor = new HttpRequestExecutor();
// HttpContext context = new BasicHttpContext(null);
// HttpHost host = new HttpHost(
// "https://api.twitter.com/oauth/request_token", 443); // use
// // 80
// // if
// // you
// // want
// // regular
// // HTTP
// // (not
// // HTTPS)
// DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
//
// context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
// context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, host);
//
// // initialize the HTTPS connection
// SSLContext sslcontext = SSLContext.getInstance("TLS");
// sslcontext.init(null, null, null);
// SSLSocketFactory ssf = sslcontext.getSocketFactory();
// for HTTP, use this instead of the above.
// Socket socket = new Socket(host.getHostName(), host.getPort());
// conn.bind(socket, params);
// BasicHttpEntityEnclosingRequest request2 = new BasicHttpEntityEnclosingRequest(
// "POST", "https://api.twitter.com/oauth/request_token");
// request2.setEntity(new StringEntity("",
// "application/x-www-form-urlencoded", "UTF-8"));
// request2.setParams(params);
// request2.addHeader("Authorization", authorization_header_string); // this
// // is
// // where
// // we're
// // adding
// // that
// // required
// // "Authorization: BLAH"
// // header.
// httpexecutor.preProcess(request2, httpproc, context);
// HttpResponse response2 = httpexecutor.execute(request2, conn,
// context);
// //
HttpPost httppost = new
HttpPost("https://api.twitter.com/oauth/request_token");
httppost.setHeader("Authorization",authorization_header_string);
ResponseHandler<String> responseHandler = new
BasicResponseHandler();
String responseBody = httpclient.execute(httppost,
responseHandler);
oauth_token =
responseBody.substring(responseBody.indexOf("oauth_token=") + 12,
responseBody.indexOf("&oauth_token_secret="));
System.out.println(responseBody);
}
catch (ClientProtocolException cpe) {
System.out.println(cpe.getMessage());
}
catch (IOException ioe) {
System.out.println(ioe.getMessage());
}
finally {
httpclient.getConnectionManager().shutdown();
}
}
private static String computeSignature(String baseString, String keyString)
throws GeneralSecurityException, UnsupportedEncodingException {
SecretKey secretKey = null;
byte[] keyBytes = keyString.getBytes();
secretKey = new SecretKeySpec(keyBytes, "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(secretKey);
byte[] text = baseString.getBytes();
return new String(Base64.encodeBase64(mac.doFinal(text))).trim();
}
}
I would like to know, how do I solve this and get the request_token. 我想知道,我该如何解决并获取request_token。
Take a look at a library like Signpost . 看一下像Signpost这样的图书馆。 Creating the signature with all the right params and & separators is always tricky and you seem to be doing all of it. 使用所有正确的参数和&分隔符创建签名总是很棘手,您似乎正在做所有这一切。 If you are just trying it for academic reasons then read up the rfc! 如果您只是出于学术原因尝试尝试,请阅读RFC!
Assuming that your consumer key is 122595245-sPcfsJO3GRkJpjzgFLZ918OaHkxeSmwYg9WDn23Z
, you need to append an ampersand character to the end to get the signing key, as per your notes. 假设您的使用者密钥为122595245-sPcfsJO3GRkJpjzgFLZ918OaHkxeSmwYg9WDn23Z
,则需要在末尾附加一个&字符以获取签名密钥。
Your signature base string is correct (except for the oauth_callback parameter - see below), so your code may be generating an incorrect signature. 您的签名基本字符串是正确的(oauth_callback参数除外-参见下文),因此您的代码可能生成了错误的签名。 You can check your signature using an online signature generator such as the LinkedIn OAuth Test Console . 您可以使用在线签名生成器(例如LinkedIn OAuth测试控制台)检查签名。
You don't appear to have included the oauth_callback parameter in your calculation. 您似乎没有在计算中包括oauth_callback参数。 This needs to be set to the url that you want the user to be redirected to when they have authorized your app, or 'oob' for PIN based authorization. 需要将其设置为您希望用户在授权您的应用程序后将其重定向到的网址,或者将其设置为基于PIN码授权的“ oob”。
By the way, if the above code includes your actual consumer key and consumer secret, I would not post them on a public forum. 顺便说一句,如果上面的代码包含您的实际消费者密钥和消费者秘密,那么我不会在公共论坛上发布它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.