I am using setup devise_token_auth for an API backend to a mobile app.
I am using:
Everything works fine with email as a provider
In order to properly implement Facebook login in the client, and still be able to authenticate on the server, I am following the method indicated in the omniauth-gem:
https://github.com/mkdynamic/omniauth-facebook See Section: Client-side Flow with Facebook Javascript SDK
which basically says to handle all login in the client, and once the user logins, redirect the client to the API callback URL at auth/facebook/callback (or omniauth/facebook/callback depending on your routes) and let Omniauth parse the signed cookie and code parameter.
Since I am using devise_token_auth, at this point the gem should suppossedly generate a token and login with provider:facebook instead of provider:email.
First I had to turn back on sessions and flash in the middleware since omniauth needs them for some reason (The Rails 5 api-only mode removes them).
But now my problem is that I am getting this error when calling GET auth/facebook/callback (or omniauth/facebook/callback) regardless of any parameters/cookies being present:
**ArgumentError (Before process_action callback :set_user_by_token has not been defined)**
Full stack trace follows.
Any help would be appreciated.
Started GET "/auth/facebook/callback" for 127.0.0.1 at 2016-05-30 14:43:47 -0500
ActiveRecord::SchemaMigration Load (0.2ms) SELECT "schema_migrations".* FROM "schema_migrations"
ArgumentError (Before process_action callback :set_user_by_token has not been defined):
activesupport (5.0.0.rc1) lib/active_support/callbacks.rb:641:in block (2 levels) in skip_callback' activesupport (5.0.0.rc1) lib/active_support/callbacks.rb:637:ineach'
activesupport (5.0.0.rc1) lib/active_support/callbacks.rb:637:in block in skip_callback' activesupport (5.0.0.rc1) lib/active_support/callbacks.rb:568:inblock in update_callbacks'
activesupport (5.0.0.rc1) lib/active_support/callbacks.rb:566:in reverse_each' activesupport (5.0.0.rc1) lib/active_support/callbacks.rb:566:in__update_callbacks'
activesupport (5.0.0.rc1) lib/active_support/callbacks.rb:636:in skip_callback' actionpack (5.0.0.rc1) lib/abstract_controller/callbacks.rb:210:inblock (3 levels) in module:ClassMethods'
actionpack (5.0.0.rc1) lib/abstract_controller/callbacks.rb:93:in block in _insert_callbacks' actionpack (5.0.0.rc1) lib/abstract_controller/callbacks.rb:92:ineach'
actionpack (5.0.0.rc1) lib/abstract_controller/callbacks.rb:92:in _insert_callbacks' actionpack (5.0.0.rc1) lib/abstract_controller/callbacks.rb:209:inblock (2 levels) in module:ClassMethods'
devise_token_auth (0.1.37) app/controllers/devise_token_auth/omniauth_callbacks_controller.rb:5:in <class:OmniauthCallbacksController>' devise_token_auth (0.1.37) app/controllers/devise_token_auth/omniauth_callbacks_controller.rb:2:inmodule:DeviseTokenAuth'
devise_token_auth (0.1.37) app/controllers/devise_token_auth/omniauth_callbacks_controller.rb:1:in <top (required)>' activesupport (5.0.0.rc1) lib/active_support/dependencies.rb:477:inload'
activesupport (5.0.0.rc1) lib/active_support/dependencies.rb:477:in block in load_file' activesupport (5.0.0.rc1) lib/active_support/dependencies.rb:662:innew_constants_in'
activesupport (5.0.0.rc1) lib/active_support/dependencies.rb:476:in load_file' activesupport (5.0.0.rc1) lib/active_support/dependencies.rb:375:inblock in require_or_load'
activesupport (5.0.0.rc1) lib/active_support/dependencies.rb:37:in block in load_interlock' activesupport (5.0.0.rc1) lib/active_support/dependencies/interlock.rb:12:inblock in loading'
activesupport (5.0.0.rc1) lib/active_support/concurrency/share_lock.rb:117:in exclusive' activesupport (5.0.0.rc1) lib/active_support/dependencies/interlock.rb:11:inloading'
activesupport (5.0.0.rc1) lib/active_support/dependencies.rb:37:in load_interlock' activesupport (5.0.0.rc1) lib/active_support/dependencies.rb:358:inrequire_or_load'
activesupport (5.0.0.rc1) lib/active_support/dependencies.rb:511:in load_missing_constant' activesupport (5.0.0.rc1) lib/active_support/dependencies.rb:203:inconst_missing'
activesupport (5.0.0.rc1) lib/active_support/inflector/methods.rb:270:in const_get' activesupport (5.0.0.rc1) lib/active_support/inflector/methods.rb:270:inblock in constantize'
activesupport (5.0.0.rc1) lib/active_support/inflector/methods.rb:266:in each' activesupport (5.0.0.rc1) lib/active_support/inflector/methods.rb:266:ininject'
activesupport (5.0.0.rc1) lib/active_support/inflector/methods.rb:266:in constantize' activesupport (5.0.0.rc1) lib/active_support/dependencies.rb:583:inget'
activesupport (5.0.0.rc1) lib/active_support/dependencies.rb:614:in constantize' actionpack (5.0.0.rc1) lib/action_dispatch/http/request.rb:93:incontroller_class'
actionpack (5.0.0.rc1) lib/action_dispatch/routing/route_set.rb:44:in controller' actionpack (5.0.0.rc1) lib/action_dispatch/routing/route_set.rb:30:inserve'
actionpack (5.0.0.rc1) lib/action_dispatch/routing/mapper.rb:16:in block in <class:Constraints>' actionpack (5.0.0.rc1) lib/action_dispatch/routing/mapper.rb:46:inserve'
actionpack (5.0.0.rc1) lib/action_dispatch/journey/router.rb:39:in block in serve' actionpack (5.0.0.rc1) lib/action_dispatch/journey/router.rb:26:ineach'
actionpack (5.0.0.rc1) lib/action_dispatch/journey/router.rb:26:in serve' actionpack (5.0.0.rc1) lib/action_dispatch/routing/route_set.rb:725:incall'
actionview (5.0.0.rc1) lib/action_view/digestor.rb:12:in call' omniauth (1.3.1) lib/omniauth/strategy.rb:186:incall!'
omniauth (1.3.1) lib/omniauth/strategy.rb:164:in call' omniauth (1.3.1) lib/omniauth/strategy.rb:186:incall!'
omniauth (1.3.1) lib/omniauth/strategy.rb:164:in call' omniauth (1.3.1) lib/omniauth/builder.rb:63:incall'
rack-attack (4.4.1) lib/rack/attack.rb:100:in call' rack (2.0.0.rc1) lib/rack/session/abstract/id.rb:222:incontext'
rack (2.0.0.rc1) lib/rack/session/abstract/id.rb:216:in call' actionpack (5.0.0.rc1) lib/action_dispatch/middleware/cookies.rb:613:incall'
warden (1.2.6) lib/warden/manager.rb:35:in block in call' warden (1.2.6) lib/warden/manager.rb:34:incatch'
warden (1.2.6) lib/warden/manager.rb:34:in call' rack (2.0.0.rc1) lib/rack/etag.rb:25:incall'
rack (2.0.0.rc1) lib/rack/conditional_get.rb:25:in call' rack (2.0.0.rc1) lib/rack/head.rb:12:incall'
activerecord (5.0.0.rc1) lib/active_record/migration.rb:552:in call' actionpack (5.0.0.rc1) lib/action_dispatch/middleware/callbacks.rb:38:inblock in call'
activesupport (5.0.0.rc1) lib/active_support/callbacks.rb:97:in `__run_callbacks'
activesupport (5.0.0.rc1) lib/active_support/callbacks.rb:750:in _run_call_callbacks' activesupport (5.0.0.rc1) lib/active_support/callbacks.rb:90:inrun_callbacks'
actionpack (5.0.0.rc1) lib/action_dispatch/middleware/callbacks.rb:36:in call' actionpack (5.0.0.rc1) lib/action_dispatch/middleware/executor.rb:12:incall'
actionpack (5.0.0.rc1) lib/action_dispatch/middleware/remote_ip.rb:79:in call' actionpack (5.0.0.rc1) lib/action_dispatch/middleware/debug_exceptions.rb:49:incall'
actionpack (5.0.0.rc1) lib/action_dispatch/middleware/show_exceptions.rb:31:in call' railties (5.0.0.rc1) lib/rails/rack/logger.rb:36:incall_app'
railties (5.0.0.rc1) lib/rails/rack/logger.rb:24:in block in call' activesupport (5.0.0.rc1) lib/active_support/tagged_logging.rb:70:inblock in tagged'
activesupport (5.0.0.rc1) lib/active_support/tagged_logging.rb:26:in tagged' activesupport (5.0.0.rc1) lib/active_support/tagged_logging.rb:70:intagged'
railties (5.0.0.rc1) lib/rails/rack/logger.rb:24:in call' actionpack (5.0.0.rc1) lib/action_dispatch/middleware/request_id.rb:24:incall'
rack (2.0.0.rc1) lib/rack/runtime.rb:22:in call' activesupport (5.0.0.rc1) lib/active_support/cache/strategy/local_cache_middleware.rb:28:incall'
actionpack (5.0.0.rc1) lib/action_dispatch/middleware/executor.rb:12:in call' actionpack (5.0.0.rc1) lib/action_dispatch/middleware/static.rb:136:incall'
rack (2.0.0.rc1) lib/rack/sendfile.rb:111:in call' rack-cors (0.4.0) lib/rack/cors.rb:80:incall'
railties (5.0.0.rc1) lib/rails/engine.rb:522:in call' puma (3.4.0) lib/puma/configuration.rb:224:incall'
puma (3.4.0) lib/puma/server.rb:569:in handle_request' puma (3.4.0) lib/puma/server.rb:406:inprocess_client'
puma (3.4.0) lib/puma/server.rb:271:in block in run' puma (3.4.0) lib/puma/thread_pool.rb:114:inblock in spawn_thread'
As requested, here is my application controller. The omniauth controllers are the default controllers provided by the gem. I have not modified them.
class ApplicationController < ActionController::API
include DeviseTokenAuth::Concerns::SetUserByToken
before_action :configure_permitted_parameters, if: :devise_controller?
before_action :authenticate_user_with_filter
#this method will authenticate users using devise_token_auth unless
#the controller is one of devise_token_auth
#authentication will look for uid, client and token in header calls
#and return 401 on no match
def authenticate_user_with_filter
if params[:controller]
if !params[:controller].start_with? 'devise_token_auth'
authenticate_user!
end
end
end
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:country_id, :fb_id, :fb_access_token, :code, :provider, :uid, :state, :omniauth_callback])
devise_parameter_sanitizer.permit(:account_update, keys: [:country_id, :fb_id, :fb_access_token])
end
end
BTW, I did just manage to solve this particular issue by pointing to the latest devise_token_auth master directly from Github in my Gemfile. Something must have been fixed recently, as the error just disappeared, although the version was exactly the same one which seems strange.
However, I am now receiving a different error for a different reason. Should I post it as a different question and answer this one myself?
Started GET "/auth/facebook/callback?code=AQCLHSxZ1xmAuvfIlWNU7N3edIHOPKEeBpKQDi1cbNa6ycj3lhBYKGQTjMfYIrwvDnQCdxDtLms91yG4A4fvnjiA0Afreq_d7JooMZEXcCb_gV-k2lpWSEsgRcWJmTdFNQtxnfTIxSJYBQriRtJvPiUVuJPootNEY3-14_1F3hpIzhjf9SEQXhLSLVKboLmnKd-IdnFGlx5yKBlKFbJywIzPRCokfegKlgZGPUQ1ipn3_qDCyTdAWs2Kd-cGopnohKntV8Qk2Dq3bMfDoI8p5oJl5snNf5WgnQ281xWlIS6E2KEFY-wJil4FqWxWuaawinc&state=9a9ef8294b902212af9e096be513755843660a6c20425afd" for 127.0.0.1 at 2016-05-30 18:01:47 -0500
Processing by DeviseTokenAuth::OmniauthCallbacksController#omniauth_success as */*
Parameters: {"code"=>"AQCLHSxZ1xmAuvfIlWNU7N3edIHOPKEeBpKQDi1cbNa6ycj3lhBYKGQTjMfYIrwvDnQCdxDtLms91yG4A4fvnjiA0Afreq_d7JooMZEXcCb_gV-k2lpWSEsgRcWJmTdFNQtxnfTIxSJYBQriRtJvPiUVuJPootNEY3-14_1F3hpIzhjf9SEQXhLSLVKboLmnKd-IdnFGlx5yKBlKFbJywIzPRCokfegKlgZGPUQ1ipn3_qDCyTdAWs2Kd-cGopnohKntV8Qk2Dq3bMfDoI8p5oJl5snNf5WgnQ281xWlIS6E2KEFY-wJil4FqWxWuaawinc", "state"=>"9a9ef8294b902212af9e096be513755843660a6c20425afd", "provider"=>"facebook", "omniauth_callback"=>{}}
Completed 500 Internal Server Error in 1ms (ActiveRecord: 0.0ms)
RuntimeError (No resource_class found):
/home/augusto/.rvm/gems/ruby-2.3.0@faces/bundler/gems/devise_token_auth-81fc7b40998d/app/controllers/devise_token_auth/omniauth_callbacks_controller.rb:107:in `resource_class'
/home/augusto/.rvm/gems/ruby-2.3.0@faces/bundler/gems/devise_token_auth-81fc7b40998d/app/controllers/devise_token_auth/omniauth_callbacks_controller.rb:235:in `get_resource_from_auth_hash'
/home/augusto/.rvm/gems/ruby-2.3.0@faces/bundler/gems/devise_token_auth-81fc7b40998d/app/controllers/devise_token_auth/omniauth_callbacks_controller.rb:27:in `omniauth_success'
actionpack (5.0.0.rc1) lib/action_controller/metal/basic_implicit_render.rb:4:in `send_action'
actionpack (5.0.0.rc1) lib/abstract_controller/base.rb:181:in `process_action'
actionpack (5.0.0.rc1) lib/action_controller/metal/rendering.rb:30:in `process_action'
actionpack (5.0.0.rc1) lib/abstract_controller/callbacks.rb:20:in `block in process_action'
activesupport (5.0.0.rc1) lib/active_support/callbacks.rb:126:in `call'
activesupport (5.0.0.rc1) lib/active_support/callbacks.rb:506:in `block (2 levels) in compile'
activesupport (5.0.0.rc1) lib/active_support/callbacks.rb:455:in `call'
activesupport (5.0.0.rc1) lib/active_support/callbacks.rb:101:in `__run_callbacks__'
activesupport (5.0.0.rc1) lib/active_support/callbacks.rb:750:in `_run_process_action_callbacks'
activesupport (5.0.0.rc1) lib/active_support/callbacks.rb:90:in `run_callbacks'
actionpack (5.0.0.rc1) lib/abstract_controller/callbacks.rb:19:in `process_action'
actionpack (5.0.0.rc1) lib/action_controller/metal/rescue.rb:31:in `process_action'
actionpack (5.0.0.rc1) lib/action_controller/metal/instrumentation.rb:32:in `block in process_action'
activesupport (5.0.0.rc1) lib/active_support/notifications.rb:164:in `block in instrument'
activesupport (5.0.0.rc1) lib/active_support/notifications/instrumenter.rb:21:in `instrument'
activesupport (5.0.0.rc1) lib/active_support/notifications.rb:164:in `instrument'
actionpack (5.0.0.rc1) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
actionpack (5.0.0.rc1) lib/action_controller/metal/params_wrapper.rb:248:in `process_action'
activerecord (5.0.0.rc1) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
actionpack (5.0.0.rc1) lib/abstract_controller/base.rb:126:in `process'
actionpack (5.0.0.rc1) lib/action_controller/metal.rb:190:in `dispatch'
actionpack (5.0.0.rc1) lib/action_controller/metal.rb:262:in `dispatch'
actionpack (5.0.0.rc1) lib/action_dispatch/routing/route_set.rb:50:in `dispatch'
actionpack (5.0.0.rc1) lib/action_dispatch/routing/route_set.rb:32:in `serve'
actionpack (5.0.0.rc1) lib/action_dispatch/routing/mapper.rb:16:in `block in <class:Constraints>'
actionpack (5.0.0.rc1) lib/action_dispatch/routing/mapper.rb:46:in `serve'
actionpack (5.0.0.rc1) lib/action_dispatch/journey/router.rb:39:in `block in serve'
actionpack (5.0.0.rc1) lib/action_dispatch/journey/router.rb:26:in `each'
actionpack (5.0.0.rc1) lib/action_dispatch/journey/router.rb:26:in `serve'
actionpack (5.0.0.rc1) lib/action_dispatch/routing/route_set.rb:725:in `call'
actionview (5.0.0.rc1) lib/action_view/digestor.rb:12:in `call'
omniauth (1.3.1) lib/omniauth/strategy.rb:186:in `call!'
omniauth (1.3.1) lib/omniauth/strategy.rb:164:in `call'
omniauth (1.3.1) lib/omniauth/strategy.rb:186:in `call!'
omniauth (1.3.1) lib/omniauth/strategy.rb:164:in `call'
omniauth (1.3.1) lib/omniauth/builder.rb:63:in `call'
rack-attack (4.4.1) lib/rack/attack.rb:100:in `call'
rack (2.0.0.rc1) lib/rack/session/abstract/id.rb:222:in `context'
rack (2.0.0.rc1) lib/rack/session/abstract/id.rb:216:in `call'
actionpack (5.0.0.rc1) lib/action_dispatch/middleware/cookies.rb:613:in `call'
warden (1.2.6) lib/warden/manager.rb:35:in `block in call'
warden (1.2.6) lib/warden/manager.rb:34:in `catch'
warden (1.2.6) lib/warden/manager.rb:34:in `call'
rack (2.0.0.rc1) lib/rack/etag.rb:25:in `call'
rack (2.0.0.rc1) lib/rack/conditional_get.rb:25:in `call'
rack (2.0.0.rc1) lib/rack/head.rb:12:in `call'
activerecord (5.0.0.rc1) lib/active_record/migration.rb:552:in `call'
actionpack (5.0.0.rc1) lib/action_dispatch/middleware/callbacks.rb:38:in `block in call'
activesupport (5.0.0.rc1) lib/active_support/callbacks.rb:97:in `__run_callbacks__'
activesupport (5.0.0.rc1) lib/active_support/callbacks.rb:750:in `_run_call_callbacks'
activesupport (5.0.0.rc1) lib/active_support/callbacks.rb:90:in `run_callbacks'
actionpack (5.0.0.rc1) lib/action_dispatch/middleware/callbacks.rb:36:in `call'
actionpack (5.0.0.rc1) lib/action_dispatch/middleware/executor.rb:12:in `call'
actionpack (5.0.0.rc1) lib/action_dispatch/middleware/remote_ip.rb:79:in `call'
actionpack (5.0.0.rc1) lib/action_dispatch/middleware/debug_exceptions.rb:49:in `call'
actionpack (5.0.0.rc1) lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'
railties (5.0.0.rc1) lib/rails/rack/logger.rb:36:in `call_app'
railties (5.0.0.rc1) lib/rails/rack/logger.rb:24:in `block in call'
activesupport (5.0.0.rc1) lib/active_support/tagged_logging.rb:70:in `block in tagged'
activesupport (5.0.0.rc1) lib/active_support/tagged_logging.rb:26:in `tagged'
activesupport (5.0.0.rc1) lib/active_support/tagged_logging.rb:70:in `tagged'
railties (5.0.0.rc1) lib/rails/rack/logger.rb:24:in `call'
actionpack (5.0.0.rc1) lib/action_dispatch/middleware/request_id.rb:24:in `call'
rack (2.0.0.rc1) lib/rack/runtime.rb:22:in `call'
activesupport (5.0.0.rc1) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
actionpack (5.0.0.rc1) lib/action_dispatch/middleware/executor.rb:12:in `call'
actionpack (5.0.0.rc1) lib/action_dispatch/middleware/static.rb:136:in `call'
rack (2.0.0.rc1) lib/rack/sendfile.rb:111:in `call'
rack-cors (0.4.0) lib/rack/cors.rb:80:in `call'
railties (5.0.0.rc1) lib/rails/engine.rb:522:in `call'
puma (3.4.0) lib/puma/configuration.rb:224:in `call'
puma (3.4.0) lib/puma/server.rb:569:in `handle_request'
puma (3.4.0) lib/puma/server.rb:406:in `process_client'
puma (3.4.0) lib/puma/server.rb:271:in `block in run'
puma (3.4.0) lib/puma/thread_pool.rb:114:in `block in spawn_thread'
This particular issue
ArgumentError (Before process_action callback :set_user_by_token has not been defined)
is fixed by pointing to the latest devise_token_auth master directly to Github in your Gemfile
gem 'devise_token_auth', :git => 'git://github.com/lynndylanhurley/devise_token_auth.git'
Run bundle update and the error goes away.
My subsequent error was a routing issue which was particular to my application