I’ve got a new little hobby grails project that relies on a user’s tweets to power its data collection, so I’ve been exploring using Twitter’s oauth features to do away user accounts altogether. My little project is called “Twitter Until You’re Fitter” and the idea is that I can tweet my weight “@tuyf 93kg” each week, and the app will pick up the value and graph it over time toward my goal weight (85kg). Given my current gym workload, that shouldn’t be too far away :-)
For those of you who haven’t played with oauth, it’s one of those emerging “federated SSO” type protocols. You generate a signed request from your application and sent it off to twitter. Twitter asks the logged on user whether they wish to allow your application access their account. If they agree, twitter will send your application an oauth_verifier which you can use to logon as that user. Generating and processing all those tokens is easily handled by twitter4j
In order to get started, you first have to register your application with twitter, after which you’ll be issued with a “consumer key” and a “consumer secret”. You’ll want to squirrel those away in your /grails-app/conf/Config.groovy to get access to them later:
twitter { oauth.consumer_key = 'd8sfsv9s0afs89v0sdesvs0' oauth.consumer_secret = 'lfsdDKSFjepfskvespfseruDFESilsfesfiseLFS==' }
Next up we’ll taked advantage of Grails 1.2’s new dependency management gear, by adding twitter4j to our /grails-app/conf/BuildConfig.groovy
dependencies { build 'net.homeip.yusuke:twitter4j:2.0.10' }
With our dependency in place, and our keys all set aside in config, it’s time to generate a request to send the user off to twitter. I’ve setup a little TwitterService class to abstract some of the details:
class TwitterService { def generateRequestToken(twitter, callbackUrl) { def consumerKey = ConfigurationHolder.config.twitter.oauth.consumer_key def consumerSecret = ConfigurationHolder.config.twitter.oauth.consumer_secret twitter.setOAuthConsumer(consumerKey, consumerSecret) def requestToken = twitter.getOAuthRequestToken(callbackUrl) return requestToken } }
I’m passing in the twitter4j object itself, since I’m planning on binding that object to the user’s session, and using it to access their timeline. Now we just need a controller to generate the “redirect to login” feature of my application. Something like this should do it:
def requestLogin = { def twitterClient = new twitter4j.Twitter() def returnUrl = g.createLink(controller: 'oauth', action: 'processLogin', absolute:true).toString() log.debug "Generating request with return url of [${returnUrl}]" def requestToken = twitterService.generateRequestToken(twitterClient, returnUrl) session.twitter = twitterClient session.requestToken = requestToken redirect(url:requestToken.getAuthorizationURL()) }