Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Facebook login - Redirect issue #166

Closed
c0mrade opened this issue Mar 1, 2015 · 19 comments
Closed

Facebook login - Redirect issue #166

c0mrade opened this issue Mar 1, 2015 · 19 comments

Comments

@c0mrade
Copy link

c0mrade commented Mar 1, 2015

Hello,

I've tried to implement a facebook login and first started by adding a button :

<button ng-click="authenticate('facebook', {params: oAuthForm})" class="btn btn-primary">Facebook</button>

And have my app configured like so :

config(['$authProvider', function($authProvider) {
      $authProvider.configure({
        apiUrl: '/api/v1',
        authProviderPaths: {
          facebook: '/auth/facebook',
          google:   '/auth/google'
        }
      });

Have my onmniauth.rb initializer setup like so :

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :facebook,      ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'], :scope => 'email,user_birthday'
end

And Facebook configured like I normally do, with app turn on for everyone to see with right key/secret, domain etc.

So when I click the Facebook button I pasted html for previously, the new tab opens (tested in chrome) and I'm prompted for facebook login.

I enter the facebook credentials (I wasn't logged in before), and I get redirected to this url:

http://api/v1/auth/facebook/callback#_=_

A log snippet :

Redirected to //api/v1/auth/facebook/callback
Completed 302 Found in 2365ms (ActiveRecord: 0.0ms)

Which lead me back to DeviseTokenAuth::OmniauthCallbacksController#redirect_callbacks . To be more precise this part :

redirect_route = "/#{Devise.mappings[devise_mapping].as_json["path"]}/#{params[:provider]}/callback"

Which is ok, but since the facebook login opened in a new tab, and there was no application running here, the redirect was wrong, so I changed it to this (might not be the best thing) :

redirect_route = "#{request.protocol}#{request.host_with_port}#{Devise.mappings[devise_mapping].as_json["path"]}/#{params[:provider]}/callback"

Which then redirects me to (lvh.me is localhost):

Redirected to http://lvh.me:3000/api/v1/auth/facebook/callback

Which then unveils the new issue which should be treated as a separate issue. I'll just mention what it is (from the log) :

Started GET "/api/v1/auth/facebook/callback" for 127.0.0.1 at 2015-02-28 19:21:01 -0500
Processing by DeviseTokenAuth::OmniauthCallbacksController#omniauth_success as HTML
  Parameters: {"provider"=>"facebook"}
  User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."uid" = '1386467908335711' AND "users"."provider" = 'facebook'  ORDER BY "users"."id" ASC LIMIT 1
Completed 500 Internal Server Error in 190ms

ActiveRecord::UnknownAttributeError (unknown attribute 'nickname' for User.):
  activerecord (4.2.0) lib/active_record/attribute_assignment.rb:59:in `_assign_attribute'

But assuming that my model has nickname, how would I got about solving the redirect issue described above? I'm using the latest version just in case I'm missing something devise_token_auth (~> 0.1.32.beta5)

@lynndylanhurley
Copy link
Owner

@c0mrade - what do your routes look like?

@c0mrade
Copy link
Author

c0mrade commented Mar 1, 2015

hi @lynndylanhurley

This is the output of rake routes :

Prefix Verb   URI Pattern                               Controller#Action
          new_user_session GET    /api/v1/auth/sign_in(.:format)            devise_token_auth/sessions#new
              user_session POST   /api/v1/auth/sign_in(.:format)            devise_token_auth/sessions#create
      destroy_user_session DELETE /api/v1/auth/sign_out(.:format)           devise_token_auth/sessions#destroy
             user_password POST   /api/v1/auth/password(.:format)           devise_token_auth/passwords#create
         new_user_password GET    /api/v1/auth/password/new(.:format)       devise_token_auth/passwords#new
        edit_user_password GET    /api/v1/auth/password/edit(.:format)      devise_token_auth/passwords#edit
                           PATCH  /api/v1/auth/password(.:format)           devise_token_auth/passwords#update
                           PUT    /api/v1/auth/password(.:format)           devise_token_auth/passwords#update
api_v1_auth_validate_token GET    /api/v1/auth/validate_token(.:format)     devise_token_auth/token_validations#validate_token
       api_v1_auth_failure GET    /api/v1/auth/failure(.:format)            devise_token_auth/omniauth_callbacks#omniauth_failure
                           GET    /api/v1/auth/:provider/callback(.:format) devise_token_auth/omniauth_callbacks#omniauth_success
                           GET    /api/v1/auth/:provider(.:format)          redirect(301)
                      root GET    /                                         application#index
                           GET    /app/*path(.:format)                      application#index
                           GET    /omniauth/:provider/callback(.:format)    devise_token_auth/omniauth_callbacks#redirect_callbacks

And the routes.rb :

namespace :api, defaults: { format: :json } do
    scope :v1 do
      #mount_devise_token_auth_for 'User', at: 'auth'
      #resources :users
    end
  end

  mount_devise_token_auth_for 'User', at: '/api/v1/auth'

  # You can have the root of your site routed with "root"
  root 'application#index'
  get 'app/*path' => 'application#index'

@lynndylanhurley
Copy link
Owner

@c0mrade - what happens when you try to use the nested version of mount_devise_token_auth_for? (The one that's commented out)

@c0mrade
Copy link
Author

c0mrade commented Mar 1, 2015

@lynndylanhurley I had issues before with this(nested version of mount..), but the workaround got to work and I just continued with that. Not able to find it now, not sure if you recall or not I've opened a issue for that case.

@lynndylanhurley
Copy link
Owner

Oh right, I remember now. The routing system was refactored to support namespacing and scoping, and I'm wondering if the refactor may have broken the previous method of mounting the routes.

Can you try using the nested version and see if it resolves the issue?

@c0mrade
Copy link
Author

c0mrade commented Mar 1, 2015

hey @lynndylanhurley good catch. Tried this :

namespace :api, defaults: { format: :json } do
    scope :v1 do
      mount_devise_token_auth_for 'User', at: 'auth'
    end
  end

The login with username/password works now.

However if I try to login with facebook I get this error :

undefined method `[]' for nil:NilClass

In this bit :

# before authentication.
      devise_mapping = request.env['omniauth.params']['resource_class'].underscore.to_sym
      redirect_route = "/#{Devise.mappings[devise_mapping].as_json["path"]}/#{params[:provider]}/callback"

The log :

NoMethodError (undefined method `[]' for nil:NilClass):
  devise_token_auth (0.1.32.beta5) app/controllers/devise_token_auth/omniauth_callbacks_controller.rb:12:in `redirect_callbacks'
  actionpack (4.2.0) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
  actionpack (4.2.0) lib/abstract_controller/base.rb:198:in `process_action'
  actionpack (4.2.0) lib/action_controller/metal/rendering.rb:10:in `process_action'
  actionpack (4.2.0) lib/abstract_controller/callbacks.rb:20:in `process_action'

@c0mrade
Copy link
Author

c0mrade commented Mar 1, 2015

@lynndylanhurley I just debugged this bit and here is the problem :)

devise_mapping = request.env['omniauth.params']['resource_class'].underscore.to_sym is :user but the Devise.mappings is this :

Devise.mappings
=> {:api_user=>
  #<Devise::Mapping:0x53dbb696
   @class_name="User",
   @controllers={:sessions=>"devise_token_auth/sessions", :registrations=>"devise_token_auth/registrations", :passwords=>"devise_token_auth/passwords", :confirmations=>"devise_token_auth/confirmations"},
   @failure_app=Devise::FailureApp,
   @format=nil,
   @klass=#<Devise::Getter:0x54ef43b1 @name="User">,
   @modules=[:database_authenticatable, :recoverable],
   @path="auth",
   @path_names={:registration=>"", :new=>"new", :edit=>"edit", :sign_in=>"sign_in", :sign_out=>"sign_out", :password=>"password"},
   @path_prefix="/api/v1",
   @router_name=nil,
   @routes=[:session, :password],
   @scoped_path="api/users",
   @sign_out_via=:delete,
   @singular=:api_user,
   @strategies=[:database_authenticatable],
   @used_helpers=[:session, :password],
   @used_routes=[:session, :password]>}

so the :api_user is supposed to be :user

@lynndylanhurley
Copy link
Owner

Oh interesting. That does look like a bug. It's strange though, because the test case is almost identical to yours and the tests are all passing.

What version of Devise do you have installed?

@c0mrade
Copy link
Author

c0mrade commented Mar 1, 2015

Yes indeed very strange.

Devise version is devise (3.4.1)

I guess something similar is in #119

@lynndylanhurley
Copy link
Owner

The question is, why does the Devise mapping represent the User model as :auth_user in the mappings hash. Is your User model nested within an Api module?

@c0mrade
Copy link
Author

c0mrade commented Mar 1, 2015

@lynndylanhurley Actually its represented it as :api_user when the routes are nested :

namespace :api, defaults: { format: :json } do
    scope :v1 do
      mount_devise_token_auth_for 'User', at: 'auth'
    end
  end

When routes are not nested :

namespace :api, defaults: { format: :json } do
    scope :v1 do
      #mount_devise_token_auth_for 'User', at: 'auth'
    end
  end

mount_devise_token_auth_for 'User', at: '/api/v1/auth'

Then the devise mappings use :user

@lynndylanhurley
Copy link
Owner

@c0mrade - thanks for your patience with this issue. I'll dig in tomorrow morning and see if I can replicate the behavior.

@c0mrade
Copy link
Author

c0mrade commented Mar 1, 2015

no problem, thank you for developing the wonderful gems.

I just got back to developing my app, first time creating angular app. Surely will be fun.

thanks for your time, let me know if you want me to try something else

@oleg-kiviljov
Copy link

Hello! Any updates on this one? I have the same problem with Devise.mappings being :api_v1_user

@varandasi
Copy link

Having the same problem, with the namescope in routes or without it. Rails 5 and the latest code in master.

@zachfeldman
Copy link
Contributor

Hi there @c0mrade ,

In an effort to cleanup this project and prioritize a bit, we're marking issues that haven't had any activity in a while with a "close-in-7-days" label. If we don't hear from you in about a week, we'll be closing this issue. Obviously feel free to re-open it at any time if it's the right time or this was done in error!

If you are still having the issue (especially if it's a bug report) please refer to our new Issue Template to provide some more details to help us solve it.

Hope all is well.

@c0mrade
Copy link
Author

c0mrade commented Oct 7, 2017

hey @zachfeldman no, not having problems anymore, this is good to close, it's an old issue.

@mrgustavorb
Copy link

guys, some response about the problem? i 'm very confused about how a setting a omniauth provider with this gem.

Someone can help me?

@zachfeldman
Copy link
Contributor

Hi @gustavosantiago this is a closed issue. If you are having an issue, please open a new one and follow the issue template. We'll try to help you troubleshoot there - keep in mind that this is a volunteer run project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants