Can anyone help me get to the bottom of this problem?
I’m using Devise + Omniauth in a Rails 3.2 app. What I want to know is, what’s happening behind the scenes with Devise’s user_omniauth_authorize_path(provider) method.
I’ve had a dig through rake routes and the gem’s source, but I can’t see anything obvious that would cause the issue I’m having.
I assume this method simply calls the provider’s signin url (e.g. Twitter) and then returns to the callback path defined in routes.rb.
In my routes.rb I have
devise_for :users, :controllers => { :omniauth_callbacks => 'users/omniauth_callbacks'}
devise_scope :user do
get '/users/auth/:provider' => 'users/omniauth_callbacks#passthru'
end
In users/omniauth_callbacks_controller.rb I have
def twitter
render :text => "This works"
end
def passthru
render :text => "This doesn't work"
end
In a view I have <%= link_to "Twitter", user_omniauth_authorize_path(:twitter) %>. Clicking this link goes to Twitter where I can log in, but upon return to my app I get an error “You are already signed in”.
I can’t work out how or why this error is being generated. I should only be seeing “This works” or “This doesn’t work”.
I also have a Facebook provider set up in exactly the same way, and this works as expected.
If I replace Devise’s omniauth link with <a href="/users/auth/twitter">Twitter</a> then I get “This works”.
So this solves my issue, but its not ideal and I’d like to know why.
Can anyone shed any light?
EDIT
Rake routes looks like this:
user_omniauth_callback /users/auth/:action/callback(.:format) users/omniauth_callbacks#(?-mix:twitter|facebook)
Well, it is working for me, so it is definitely something on your end. First of all, have you compared in the console the GET calls
/users/auth/twitterand/users/auth/twitter?callbackobtained by the 2 different methods? They should look exactly the same (except for the token and the verifier, of course).Now, I’m not sure if this is related, but with devise you don’t use a passthru route, so you can remove that route. Instead, in your callbacks controller, you should implement an action called failure that handles a bad request. See here for devise’s implementation.
I’m grasping at straws here, but you should also have this at the end of your callbacks controller: