views:

3357

answers:

4

I am using the ruby twitter gem and oauth to gain access to users twitter accounts. In my code, I have:

unless @user.twitter_authd?
      oauth = Twitter::OAuth.new('token', 'secret')
      session[:twitter_request_token] = oauth.request_token.token
      session[:twitter_request_secret] = oauth.request_token.secret
      @twitter_auth_url = oauth.request_token.authorize_url
    end

where token and secret have my actual token and secret inserted. When I click on the link to the @twitter_auth_url, I am taken to twitter and asked to grant access. I click allow and then twitter redirects me to my callback URL http://www.mydomain.com/twitter%5Fcallback/?oauth%5Ftoken=fmy2aMvnjVgaFrz37bJ4JuB8r5xN79gsgDQRG4BNY which then hits this code:

oauth = Twitter::OAuth.new('token', 'secret')

    logger.info("session[:twitter_request_token] = #{session[:twitter_request_token]}")
    logger.info("session[:twitter_request_secret] = #{session[:twitter_request_secret]}")

    oauth.authorize_from_request(session[:twitter_request_token], session[:twitter_request_secret])
    session[:twitter_request_token] = nil
    session[:twitter_request_secret] = nil

    @user.update_attributes({
      :twitter_token => oauth.access_token.token, 
      :twitter_secret => oauth.access_token.secret,
    })

    redirect_to root_path

The twitter request token and secret are being set just fine. However I end up with an authorization error:

 OAuth::Unauthorized in MainController#twitter_callback

401 Unauthorized

RAILS_ROOT: /Users/TAmoyal/Desktop/RoR_Projects/mls
Application Trace | Framework Trace | Full Trace

/Library/Ruby/Gems/1.8/gems/oauth-0.3.4/lib/oauth/consumer.rb:167:in `token_request'
/Library/Ruby/Gems/1.8/gems/oauth-0.3.4/lib/oauth/tokens/request_token.rb:14:in `get_access_token'
/Library/Ruby/Gems/1.8/gems/erwaller-twitter-0.6.13.1/lib/twitter/oauth.rb:29:in `authorize_from_request'
/Users/TAmoyal/Desktop/RoR_Projects/mls/app/controllers/main_controller.rb:70:in `twitter_callback'

The code is failing at this line:

oauth.authorize_from_request(session[:twitter_request_token], session[:twitter_request_secret])

when it tries to get an access token. You can see the source code of authorize_from_request here. I am not sure why this is happening. Anyone have ideas?

A: 

not enough info for me, but when was twitter gem last updated? twitter changed their oauth 'stuff' in mid may approx. perhaps you have an old one. I'd update your question to show the callback_url, and make sure you have the right token and secret, which it looks like you don't have.

also, did you put the right callback url in your twitter app page? alot of times that screws you up too.

if that fails use mbleighs twitter_auth instead. it worked for me and is pretty slick.

pjammer
I added my callback URL to the example. I know people are successfully using the Twitter gem right now, but with oauth 0.3.4 (0.3.5 broke some stuff). As far as the right token and secret, I copied the consumer key and secret straight from my twitter app settings...not sure how those can be wrong. The request token and secret are generated once and saved in the session, so those do not change and I'm not sure how they could be wrong either. what do you mean by "the right callback URL"? I am certainly getting redirected to the right action in my web app...doesn't that mean it's right?
Tony
+2  A: 

This was one of the most annoying things to debug that I have come across. I was outputting in a couple places by accident because the URL's are dynamic and they happened to not be defined in my test case (i use this to display chart data and there is not enough right now so the google chart api URL's are blank). This caused my browser to make multiple requests to my localhost when some pages were loaded. Somehow that made the oauth process crap out. Obviously there is no way for people on S.O. to know about my application specific issue so I had to answer my own question.

Tony
could you elaborate on this a bit? multiple requests as in redirects? or images/static files but within the same request?
Kyle
it's been a while but i think the idea is that if you have an img tag with an empty source (src="") or maybe i had (src="/"), your browser tries to load your website again for the image. so for every image with an empty source, you get an extra load
Tony
thanks tony. life saver. do you know why this would cause oauth to crap out?
ming yeow
honestly, it's been too long for me to remember why. glad this helped.
Tony
+7  A: 

A bit late to the party but just ran into the same issue myself. I tracked the issue down to the setup of my OAuth app in Twitter. I had initially not specified a callback URL as I was unsure of it.

Once I had setup my rails app I went back to find Twitter had assumed I was a desktop application as I hadn't specified a callback URL. Once I changed this to website and entered a callback URL I stopped getting 400s.

George Palmer
I did the exact same thing. Thanks for posting +1
cbrulak
what's actually the difference between desktop and web application?
Radek
@Radek - desktop and web are essentially the same. However, desktop apps can't have a callback URL as part of the authorisation process. Instead twitter generates a PIN number which is then shown to the user and they enter it into the desktop app.
Dan Diplo
@Dan Diplo: thank you for the explanation. Still wondering how the callback URL works. Is it the same url all the time and all info is stored only in headers?
Radek
@Radek - You register the callback URL when you register your app with Twitter. However, you can also specify the callback URL in your authentication request, too, which over-rides this and allows it to be dynamic. All of info is passed as headers, but it is up to the consuming app to store the final token and secret. See http://dev.twitter.com/pages/auth
Dan Diplo
What tripped me up: although you can override the callback URL in the request, if you do not enter ~something~ as the callback url when registering the application at twitter, then twitter defaults your settings back to a "client application". You won't notice this unless you go back in to edit the settings again.
tardate
A: 

this is an issue about time synchronization of your system with twitter server.

Rabia