8
2009
Log into your Grails app using your Twitter credentials
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())
}
First we generate a link for our return url after authentication, then I call the TwitterService to generate my request token. The RequestToken class exposes a getAuthorizationURL() which returns the URL you need to send them off to. The user will be shown an authorisation screen like this:
Assuming they click “Allow”, twitter will redirect back to your requested URL with a URL containing a oauth_verifier parameter. You can use that parameter to login to twitter as that user. Here’s the action that processes the return URL from twitter:
def processLogin = {
log.debug "Processing Login Return from Twitter"
if (!session.requestToken) {
redirect(action: 'requestLogin')
} else {
def accessToken = session.twitter.getOAuthAccessToken(session.requestToken, params.oauth_verifier)
log.debug "Attempting validate..."
def twitterUser = session.twitter.verifyCredentials()
log.debug "Validate successful for ${twitterUser.screenName}"
session.user = twitterUser
redirect(action: 'displayDetails')
}
}
That accessToken object turns out to be really important. If you squirrel away it’s token and tokenSecret properties, you can login as the user any time you want with the redirect step (eg. a future session, cookie value, etc).
Phew! We’ve come a long way! We’re now actually logged on as the user, now we just need a gsp to display some timeline details. Perhaps something like this:
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Welcome ${session.user.name}</title>
</head>
<body>
<h1>Successful Login for ${session.user.name}</h1>
<p>Your user handle is <a href="${session.user.getURL()}">@${session.user.screenName}</a></p>
<p>Your icon is: <img src="${session.user.profileImageURL}"></p>
<p>Your timeline:</p>
<ul>
<g:each in="${session.twitter.homeTimeline}" var="status" status='i'>
<li class="${ (i % 2) ? 'odd' : 'even'}">
<img src="${status.user.profileImageURL}"/>
${status.user.screenName} : ${status.text} </li>
</g:each>
</ul>
</body>
</html>
Which should give us an output like this:
And our application is fully linked up! If the user has a look in their Twitter settings, they’ll now see that our app has read-only access to their account. They can revoke that at any time (so we’ll need some error checking to handle that down the track).
Once I’ve got a bit more of the app running, I’ll get some source onto a public repo. Till then, I need to get ready for my Spin class..
10 Comments + Add Comment
Leave a comment
Glen Smith
Archives
- January 2012
- November 2011
- October 2011
- September 2011
- August 2011
- July 2011
- June 2011
- April 2011
- March 2011
- January 2011
- November 2010
- October 2010
- September 2010
- August 2010
- July 2010
- June 2010
- May 2010
- April 2010
- February 2010
- January 2010
- December 2009
- November 2009
- October 2009
- September 2009
- August 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- May 2007
- April 2007
- March 2007
- February 2007
- January 2007
- December 2006
- November 2006
- October 2006
- September 2006
- August 2006
- July 2006
- June 2006
- May 2006
- April 2006
- March 2006
- February 2006
- January 2006
- December 2005
- November 2005
- October 2005
- September 2005
- August 2005
- July 2005
- June 2005
- May 2005
- April 2005
- March 2005
- February 2005
- January 2005
- December 2004
- November 2004
- October 2004
- September 2004
- August 2004
- July 2004
- June 2004
- May 2004
- March 2004
- February 2004
- January 2004
- December 2003
- November 2003
- October 2003
- September 2003

An article by Glen





Hi, Glen. Thanks for article.
I have a problem.
During registration i write callback url.
In my application for Development Environment I try to rewrite callback_url but twitter redirect me to authorisation screen
Anton
Anton,
If you just need straight login, I think there’s an alternative to requestToken.getAuthorizationURL() which is something like requestToken.getAuthenticationURL() or something like that. Maybe that’s the one you’re after?
Bingo!! I got I was looking for!!.. Thanks a lot Glen.
Hi Glen! Greate Article!
Im new at grails but im lovin it!
But because im new, i didnt understand that much how to implement the code. Could you copy the controller? or paste a screenshot? Thanks a lot!
hope you’ re fitter now!
Glen:
In these lines
def consumerKey = ConfigurationHolder.config.twitter.oauth.consumer_key
def consumerSecret = ConfigurationHolder.config.twitter.oauth.consumer_secret
twitter.setOAuthConsumer(consumerKey, consumerSecret)
I needed to run consumerKey and consumerSecret with .toString(). I was getting errors that setOAuthConsumer() didn’t know how to handle ConfigurationObjects.
Grails 1.2.0
Annoying little thing, and cost me a bit of time, then I tried the toString()s on a lark and it worked.
Hope this helps someone else
thanks Glenn for this article, it works fine
Nabil
Hi,
It works just like that, i really appreciate your efforts.
I have another requirement which is logout.
When ever i logout from my application after logged in by using twitter credentials, It should be able to logout from the twitter also.
Is anyone having idea to do the same?
Thanks
Venkata
Hi Glen,
Thanks for the article, it helped. I have a question now, how to persist AccessToken? I am able to do what is mentioned above, I would like to tweet on User’s behalf at later stage but I am unable to reincarnate AccessToken using “token” and “token secret”, can you guide?
Thanks
Hi,
I have integrated Twitter4j login functionality for my project successfully with your article but on deny of logging giving me exception. Below are the steps i did
Step.1) if i click on twitter button takes me to twitter login pop up
box with “Allow” and “Deny” buttons
Step.2) if i enter proper twitter username and password, it is
redirecting me to the twitter call back url which is to my application
url.
Upto this everything is working fine.
Step.3) After (Step.1), if i click on “Deny” button it is redirecting
to the twitter popup box with some information(OK, you’ve denied
localvc access to interact with your account! Feel free to find other
applications and find out what people are talking about right now at
Twitter.).
Then closed the twitter popup box, if i comes back to my app login
page it is giving me exception “Stack Overflow”.
If i close the browser, reopen the new browser and then i could able
to access the my app login page without any problem.
How can i resolve the ‘Stack overflow exception’ issue after clicking
“Deny” button?
Is there any functionality to take care on “Deny” button?
Thanks Glen, it’s what I was looking for!