I was looking for a simple Java example using the Twitter 1.1 API and couldn't find one. Using the PHP sample posted here: Simplest PHP example for retrieving user_timeline with Twitter API version 1.1 and a few other Stackoverflow posts, I was able to come up with the following working example.
public void testUserTimelineWithAuthSample() throws Exception {
//This will read the timeline of your account.
String method = "GET";
String url = "https://api.twitter.com/1.1/statuses/user_timeline.json";
String oAuthConsumerKey = "Your value here.";
String oAuthConsumerSecret = "Your value here."; //<--- DO NOT SHARE THIS VALUE
String oAuthAccessToken = "Your value here.";
String oAuthAccessTokenSecret = "Your value here."; //<--- DO NOT SHARE THIS VALUE
String oAuthNonce = String.valueOf(System.currentTimeMillis());
String oAuthSignatureMethod = "HMAC-SHA1";
String oAuthTimestamp = time();
String oAuthVersion = "1.0";
String signatureBaseString1 = method;
String signatureBaseString2 = url;
String signatureBaseString3Templ = "oauth_consumer_key=%s&oauth_nonce=%s&oauth_signature_method=%s&oauth_timestamp=%s&oauth_token=%s&oauth_version=%s";
String signatureBaseString3 = String.format(signatureBaseString3Templ,
oAuthConsumerKey,
oAuthNonce,
oAuthSignatureMethod,
oAuthTimestamp,
oAuthAccessToken,
oAuthVersion);
String signatureBaseStringTemplate = "%s&%s&%s";
String signatureBaseString = String.format(signatureBaseStringTemplate,
URLEncoder.encode(signatureBaseString1, "UTF-8"),
URLEncoder.encode(signatureBaseString2, "UTF-8"),
URLEncoder.encode(signatureBaseString3, "UTF-8"));
System.out.println("signatureBaseString: "+signatureBaseString);
String compositeKey = URLEncoder.encode(oAuthConsumerSecret, "UTF-8") + "&" + URLEncoder.encode(oAuthAccessTokenSecret, "UTF-8");
String oAuthSignature = computeSignature(signatureBaseString, compositeKey);
System.out.println("oAuthSignature : "+oAuthSignature);
String oAuthSignatureEncoded = URLEncoder.encode(oAuthSignature, "UTF-8");
System.out.println("oAuthSignatureEncoded: "+oAuthSignatureEncoded);
String authorizationHeaderValueTempl = "OAuth oauth_consumer_key=\"%s\", oauth_nonce=\"%s\", oauth_signature=\"%s\", oauth_signature_method=\"%s\", oauth_timestamp=\"%s\", oauth_token=\"%s\", oauth_version=\"%s\"";
String authorizationHeaderValue = String.format(authorizationHeaderValueTempl,
oAuthConsumerKey,
oAuthNonce,
oAuthSignatureEncoded,
oAuthSignatureMethod,
oAuthTimestamp,
oAuthAccessToken,
oAuthVersion);
System.out.println("authorizationHeaderValue: "+authorizationHeaderValue);
System.out.println("url: "+url);
System.out.println("authorizationHeaderValue:"+authorizationHeaderValue);
GetMethod getMethod = new GetMethod(url);
getMethod.addRequestHeader("Authorization", authorizationHeaderValue);
HttpClient cli = new HttpClient();
int status = cli.executeMethod(getMethod);
System.out.println("Status:"+status);
long responseContentLength = getMethod.getResponseContentLength();
System.out.println("responseContentLength:"+responseContentLength);
String response = getMethod.getResponseBodyAsString();
System.out.println("response: "+response);
}
private static String computeSignature(String baseString, String keyString) throws GeneralSecurityException, UnsupportedEncodingException, Exception
{
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();
}
private String time() {
long millis = System.currentTimeMillis();
long secs = millis / 1000;
return String.valueOf( secs );
}
However, if I add parameters to the url like:
String url = "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=twitterapi&count=2";
I get:
response: {"errors":[{"message":"Could not authenticate you","code":32}]}
Any idea where this is going wrong?
This works excellent for Timeline with the new Twitter API 1.1
1) Download twitter4j-core-3.0.3.jar in http://twitter4j.org/en/ 2) Try use this code:
Here's a Twitter 1.1 API example that works with parameters. The issue was not related to the nonce. It was the signatureBaseString. Think of the signatureBaseString as a 3 part string delimited by the ampersand (METHOD&URL&PARAMS). The api parameters are NOT to be included in the 2nd part of the signatureBaseString, they are to be included (with the other 6 security parameters) in the last part of signatureBaseString (Also, those params must be in alphabetic order).
Where the NvpComparator is:
}
You are wrong with the
oauth_nonce
. It is a random 32 bytes string encoded in base 64.You can build them like this :
With
String toBase64(String);
which is a method to encode a String with Base 64.Here is my solution using twitter4j lib