Twitter turned off basic authentication. Finally. Henceforth, you can't log into Twitter via its API in the traditional sense; accordingly, the following code, which uses Twitter4J isn't valid any longer:
Twitter twitter = new TwitterFactory().getInstance( "some user" , "some password" ); |
If you try that these days, you should see a nasty JSON message as a response stating along the lines of {"code":53, "message":"Basic authentication is not supported"}
.
Instead, Twitter now requires OAuth for authenticating requests, which isn't so bad; however, if you intend to use Twitter4J, things get complicated quickly namely because the current exampleslisted don't actually work. Because it's my bag, I aim to set the record straight though.
OAuth isn't terribly complicated; nevertheless, if you read the various documents related to it, you'll most likely end up confused. There are various forms of OAuth and things are different depending on desktop or mobile or web applications. In short, however, OAuth basically means two things:
- applications don't need to store a login and password
- apps now delegate authorization to a trusted location — i.e. twitter
It's all done with various tokens that are traded. Accordingly, the first step to get working with OAuth for web applications is to register your application with Twitter. You'll need to provide a few pieces of information — key is a callback URL, which can be changed at runtime.
You'll be given a few datums in return: namely a consumer key and a consumer secret. You'll need those to get things started. Obviously, don't share the secret.
Next, you'll do two things — ask the user to sign into Twitter (in this step you'll send some information to Twitter) and then when the user grants you permission, Twitter will invoke your callback URL. At this endpoint, you'll need to grab another token. Then you'll have the credentials to act upon a user's behalf going forward.
I'm going to demonstrate this with a simple web application written with The Play Framework, which is a nifty Java based framework similar in ways to something like Rails or Grails. One thing I particularly like about Play is its ability to get a web application up and running without a domain model. This is distinctly different than Grails, which is definitely a fancy, rapid web application development framework, but which stresses a model first. Play seems to stress controllers upfront with less emphasis on domains. Thus, with Play, I can quickly demonstrate a two step OAuth flow without having to worry about a model.
As Play is a Java framework (it does leverage Groovy under the covers in some places), you end up writing everything in Java. Endpoints are written in classes that extend Play's Controller
type and are methods that begin with public static void
. Thus, my first endpoint is dubbedlogin
, which is invoked after a user clicks a link asking them to log into Twitter:
public static void login() { Twitter twitter = new TwitterFactory().getOAuthAuthorizedInstance( "r4...w" , "j4...2" ); try { RequestToken requestToken = twitter.getOAuthRequestToken( session.put( "requestToken_token" , requestToken.getToken()); session.put( "requestToken_secret" , requestToken.getTokenSecret()); redirect(requestToken.getAuthorizationURL()); } catch (Exception e) { e.printStackTrace(); } } |
As you can see above, a TwitterFactory
instance is created with my consumer key and secret. Then, a RequestToken
instance is obtained and in doing so, I pass in my own callback URL (http://localhost:9000/application/callback), which Twitter will invoke after a person grants access. Lastly, two pieces of information is placed into Play's session
object, which isn't a typical Servlet Session, but really a cookie. Those two pieces of information will be required when things get transferred back to your web application. Lastly, the browser is then redirected to an authorization URL on Twitter's website.
The callback URL invokes the following endpoint:
public static void callback(String oauth_token, String oauth_verifier) { Twitter twitter = new TwitterFactory().getOAuthAuthorizedInstance( "90...2" , "3ee.." ); AccessToken accTok = null ; try { accTok = twitter.getOAuthAccessToken( session.get( "requestToken_token" ), session.get( "requestToken_secret" ), oauth_verifier); } catch (Exception e) { e.printStackTrace(); } //... do twitter stuff.... } |
Play endpoints can have parameters, which incoming HTTP parameters are bound to via name — as you can see, Twitter passes back two parameters: oauth_token
& oauth_verifier
. Accordingly, I only need one — the oauth_verifier
, which is used in concert with the two tokens held in a cookie to obtain an AccessToken
instance.
Going forward for the remainder of this session, my twitter
instance is authorized — I can do things on behalf of the user who granted my application access to their account (such as update status, etc). If I chose to do things on their behalf in the future, I can reuse the required tokens. All I need to do is save the oauth_verifier
for this user or the AccessToken
itself, etc.
Now that you're familiar with OAuth and Twitter4J's APIs, go forth and build Twitter applications,
0 件のコメント:
コメントを投稿