Skip to content

OmniAuth with multiple models

Guilherme Simões edited this page Dec 27, 2013 · 2 revisions

Currently, Devise's Omniauthable module does not work with multiple models. No need to worry though, as the Omniauthable module is but a simple wrapper around OmniAuth.

So to allow OmniAuth authentication for multiple models:

  1. Remove the :omniauthable argument from your models.

  2. Move the OmniAuth configuration out of Devise's configuration file and into a new file. So, instead of having this in devise.rb:

Devise.setup do |config|
  config.omniauth :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET']
end

You now have this in your new file omniauth.rb:

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET']
end
  1. Create your own OmniAuth routes. Here's an example of a possible route, given you have an authentications_controller.rb:
get "/auth/:action/callback", :to => "authentications", :constraints => { :action => /twitter|google/ }

Or if you want all OmniAuth authentications to be directed to the same create action, independently of the provider used:

get "/auth/:provider/callback" => "autentications#create"
  1. Setup OmniAuth's on_failure hook. You can do this inside OmniAuth's configuration block:
Rails.application.config.middleware.use OmniAuth::Builder do
  on_failure { |env| AuthenticationsController.action(:failure).call(env) }
end

Or outside of it:

OmniAuth.config.on_failure = Proc.new { |env| AuthenticationsController.action(:failure).call(env) }

Devise implements this second option, but the first option is simpler since OmniAuth is already being configured on the omniauth.rb file.

  1. Handle OmniAuth failures. Since errors in this library aren't properly standardized, the only way to handle them is with lots of conditionals, like Devise is doing. Simply copy the relevant code and you should be good to go.

The Railscast on Simple OmniAuth should also help setting this up.

Clone this wiki locally