Richard Hart

Head of Something @ Somewhere
Kent, UK

My Music
My Photos

LinkedIn
Mastodon

Devise Omniauth Dynamic Providers

My current project www.viewshound.com requires different users to have different scopes for their Facebook authentication. Warden supports dynamic providers out of the box. To get it working with Devise was pretty easy, just a couple of minor changes were needed especially to support Facebook.

First up was creating the new route. As I’m using a controller called Omniauth and not Session, the :to attribute is different. The other thing to note is I’m matching /users/auth/facebook/setup, not /auth/facebook/setup like in the Warden documentation.

routes.rb


  devise_for :users, 
      :controllers => { :omniauth_callbacks => "omniauth" }, 
      :skip => [:sessions] do
    match '/users/auth/facebook/setup', :to => 'omniauth#setup'
  end

Next we create the new setup action for Warden to call. The docs use consumer_key and consumer_secret, but facebook expects client_id and client_secret, so be sure to use those instead. This is where I make changes to the scope based on the current user if they are signed in or not. So a user can re-authenticate with Facebook to get more permissions for their account if they wish.

omniauth_controller.rb


  class OmniauthController < Devise::OmniauthCallbacksController

    def setup
      request.env['omniauth.strategy'].client_id = 
           {your_facebook_id_here}
      request.env['omniauth.strategy'].client_secret = 
           {your_facebook_secret_here}
      request.env['omniauth.strategy'].options = 
           {:scope => your_facebook_scope_here}
      render :text => "Setup complete.", :status => 404
    end

  end

Finally change the devise.rb initializer to support the new setup.

devise.rb


  config.omniauth :facebook, nil, nil, :setup => true

Restart your application and you should be good to go.