-
Notifications
You must be signed in to change notification settings - Fork 5.5k
OmniAuth with multiple models
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:
-
Remove the
:omniauthable
argument from your models. -
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
- Create your own OmniAuth routes. Here's an example of a possible route, given you have an
authentications_controller.rb
:
For Rails 3 and 4:
get "/auth/:action/callback", :to => "authentications", :constraints => { :action => /twitter|google/ }
For Rails 5:
get "/auth/:action/callback", :controller => "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" => "authentications#create"
For Rails 6:
get "/auth/twitter/callback" => "authentications#twitter"
get "/auth/google/callback" => "authentications#google"
If you get a mapping error, wrap the route in a devise_scope
:
devise_scope :user do
get "/auth/:provider/callback" => "authentications#create"
end
- 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.
With this set up, all authentication failures (such as a user cancelling logging in) will be redirected to the `failure` action in the `authentications_controller.rb`.
- 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.