Quick and Dirty Twitter4j OAuth for Web Apps
This simple tutorial is a result of my trying to oauth to twitter using Twitter4j. It is actually part of my thesis in my university, a small functionality in a much wider application.
Anyway, I have been googling tutorials on how to use Twitter4j in a web app but I haven’t found much. The Twitter4j has examples but most of them in are written in a main method. I did find some leads in the Twitter4j google group and much to my surprise, the key to accessing data in Twitter using Twitter4j/Oauth is knowing how Oauth works in the first place.
This tutorial isn’t about how to use the oauth protocol there are many resources in the net about that .
Try here, here and well, here.
Although this code works, it might not be the right way to use Twitter4j and Oauth. It might not be optimized and it’s definitely not the best way. It’s actually riddled with bad practices! Although in my real app, I have refactored those code smells already.
UPDATE: Here’s a refactored solution that I did.
Another thing, I have yet to address why Twitter’s icon shows up after it redirects to the to callback url. I intend to work on that issues soon as well as optimizing the method. Comments and suggestions are highly welcome!
First, Register your web app with Twitter and set there the callback url of your app. That’s the url the user is redirected to after authorization. Once you’ve registered your app, you’ll be provided with a consumer key and consumer secret that is unique to your app.
The code:
In a first servlet, You need to print the the authorization url so the user can click on it and he/she can authorize your web app to be able to access your Twitter account.
Get a request token
Twitter twitter = new Twitter();
twitter.setOAuthConsumer("consumerkey", "consumersecret");
RequestToken twitterRequestToken
= twitter.getOAuthRequestToken();
Get the token and tokenSecret and then find a way to persist them.
String token = twitterRequestToken.getToken(); String tokenSecret = twitterRequestToken.getTokenSecret(); persist(token,tokenSecret);
Print the authorization url in a jsp. I am using Spring’s abstract controller in my app and my model is a hashtable since I am printing so many things. This part is also up to you.
String authorizationUrl = twitterRequestToken.
getAuthorizationURL();
pageProperties.put("twitterAuthUrl",authorizationURL);
When the user sees the link and clicks on it, he/she is directed to Twitter and it asks for his/her authorization. After this the user is directed to the callback url. This is usually a second servlet but in my app it’s just another Spring abstract controller.
In a second servlet, retrieve the token and tokenSecret you persisted in the first servlet. Once that is done, get an access token
Twitter twitter = new Twitter();
twitter.setOAuthConsumer("consumerkey", "consumersecret");
AccessToken accessToken =
twitter.getOAuthAccessToken(token, tokenSecret);
twitter.setOAuthAccessToken(accessToken);
Again, persist the token and tokenSecret that comes with the accessToken for later use.
persist(
accessToken.getToken(),
accessToken.getTokenSecret()
);
Once that’s out of the way, use the Twitter
instantiations many service methods to be able to access a user’s
account.
int id = accessToken.getUserId(); User user = twitter.showUser(id+""); String screenName = user.getScreenName();
So there you go, a quick and dirty Twitter4j Oauth for web apps.
[...] http://jeungun.wordpress.com/2009/09/03/quick-and-dirty-twitter4j-oauth-for-web-apps/ Categories: 1 Comments (0) Trackbacks (0) Leave a comment Trackback [...]
My Quick and Dirty Twitter4j OAuth for Web Apps « Research Log of Web Science Students
September 3, 2009 at 5:26 pm
[...] Quick and Dirty Twitter4j OAuth for Web Apps [...]
Tutorial: Java based Twitter App on Google App Engine
October 2, 2009 at 9:13 pm
[...] Comment! This is a refactored version of my post, Quick and Dirty Oauth for Twitter4J OAuth for Web Apps [...]
OAuth with Client Libraries (GData, Twitter4J) and Spring MVC « From the left flank
October 3, 2009 at 4:31 pm
[...] my Software Engineering problem Like I did with my Twitter4J solution. I stored the token and tokenSecret to session and used it at the callback to get an access [...]
Problems Solved. « Research Log of Web Science Students
October 10, 2009 at 9:44 am
Hello:
I have been struggling with debugging oauth for quite a few hours now. I have gone through your blog several times with no luck. It’s something really small I am missing
and any help would be greatly appreciated. Here is my code.
On my jsp page, when the user clicks on ‘Sign in with Twitter’ button, I do the following:
Twitter twitterObj = new Twitter()
twitterObj.setOAuthConsumer(consumerKey, consumerSecret)
RequestToken twitterRequestToken = twitterObj.getOAuthRequestToken()
session.token = twitterRequestToken.getToken()
session.tokenSecret = twitterRequestToken.getTokenSecret()
redirect(twitterRequestToken.getAuthorizationURL())
The user is sent over the Twitter where they either type in username/password, or simply hit Allow. After hitting allow, my callback URL is getting called.
Twitter twitterObj = new Twitter()
twitterObj.setOAuthConsumer(consumerKey, consumerSecret)
AccessToken accessToken = twitterObj.getOAuthAccessToken
(session.token, session.tokenSecret)
twitterObj.setAccessToken(accessToken)
I get the following exception:
twitter4j.TwitterException: The user has not given access to the account.
at twitter4j.http.HttpClient.getOAuthAccessToken
(HttpClient.java:222)
at twitter4j.Twitter.getOAuthAccessToken(Twitter.java:181)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke
(NativeMethodAccessorImpl.java:39)
…
Caused by: twitter4j.TwitterException: 401:Authentication credentials were missing or incorrect.
at twitter4j.http.HttpClient.httpRequest(HttpClient.java:477)
at twitter4j.http.HttpClient.getOAuthAccessToken
(HttpClient.java:220)
… 83 more
Thanks in advance,
Bilal
Bilal Ahmed
December 3, 2009 at 4:47 am
Could you tell us what line your code is causing this error?
Jose Asuncion
December 3, 2009 at 3:35 pm
Hi Jose,
The exception is happening on this line,
AccessToken accessToken = twitterObj.getOAuthAccessToken(session.token, session.tokenSecret)
when I get the callback, and my method tries to retrieve the access token. I am printing token string and token secret correctly, so I know the values are there.
Thanks,
Bilal
Bilal Ahmed
December 3, 2009 at 4:15 pm
Hmmmmm, if what you’re saying is true then I don’t know actually. I’ll try to do oauth again on my end, and then deploy the app on the net. Will get back to you. Hold on.
Jose Asuncion
December 3, 2009 at 6:10 pm
Thanks a bunch Jose
On the side note, I am dropping a cookie for the username once authenticated. Next time user tries to authenticate I will look up oauth token and secret in the database. One issue I saw was since twitter doesn’t expire the oauth token, it’s the application provider’s responsibility to expire it periodically. This way, the token doesn’t get abused. I would love to hear any insights you have regarding that.
Cheers!
Bilal
Bilal Ahmed
December 3, 2009 at 8:47 pm
Hi Jose!
Thank you for the information! I found it helpful. But I’m currently stuck somewhere – I don’t know what to do with the persisted access token and token secret. how do i use it such that my application has permanent authentication to twitter without having to always grant permission from the user’s end?
Thanks a lot!
Regards,
Savio
Savio
December 24, 2009 at 6:30 pm
Hi Savio, you have to store/persist the token and token secret to some kind of database like MySQL or in my case I am using AppEngine DataStore.
Then you can retrieve them again without having to always grant permission from the user’s end.
Twitter twitter = new Twitter();
twitter.setOAuthConsumer(“consumerkey”, “consumersecret”);
AccessToken accessToken =
twitter.getOAuthAccessToken(token, tokenSecret);
twitter.setOAuthAccessToken(accessToken);
Jose Asuncion
December 24, 2009 at 6:36 pm
i would like to know if you have a solution!
Savio
December 24, 2009 at 6:31 pm
Hi Jose!
Thanks a lot for your work! it really help. I figured what method to call to use the access token and the access token secret.
twitter.setOAuthAccessToken(dataStore.getAccessToken() , dataStore.getAccessTokenSecret() );
thanks a lot for your work!
Savio
Savio
December 24, 2009 at 7:11 pm
Hi Jose,
I found out the problem. This article helped a lot, showing code from grails.
http://blogs.bytecode.com.au/glen/2009/12/08/log-into-your-grails-app-using-your-twitter-credentials.html
The solution is that you should keep the twitter object and request token object in the session. When the call back happens, use the same session object to pull out access token. Also, use the request token to generate the auth URL.
Cheers,
Bilal
Bilal Ahmed
December 30, 2009 at 5:12 am
Hi Bilal, good to see you solved your problem! Hope my blogpost was able to help you somehow. Happy new year!
Jose Asuncion
December 31, 2009 at 6:49 pm
Your blogpost is awesome Jose and that really got me started
Hope you are having great holidays and happy new year.
Bilal
Bilal Ahmed
December 31, 2009 at 7:16 pm
Ho Jose,
Thank you for your post. I have just used it to start my new Twitter project with Twitter4J.
I have found a small bug in your last code snippet : Need to pass the id as an int not as a String. The String argument matches the signature of a similar method that requests user by his screen name not his ID.
Thanks
Itzik
Itzik yatom
February 8, 2010 at 8:43 am
Hi there! It’s been since I last checked if the code I have here is correct. The version of Twitter4J I was using back then was Twitter4J 2.0.9 and I haven’t been using it since then. Maybe the something changed in the library. Thanks for mentioning it anyway. Goodluck on your project!
Jose Asuncion
February 8, 2010 at 7:39 pm