How to create multiple Facebook Omniauth strategies for the same application

by-web development

In a previous post, I talked about testing Facebook login with capybara. Today I just want to share a quick “recipe” that I used to create multiple Facebook logins. Let me explain.

What is the problem?

In the next version of myDrinkaware, we have a fairly common Facebook login button.

Using Devise and Omniauth, this is defined in your initializer with:

config.omniauth :facebook, APP_API, APP_SECRET

But my problem was that I needed 3 different sorts of login! 1 for the website and 2 for Facebook apps, which are embedded in the code.

I couldn’t use the same login Strategy because I needed the :iframe option on the Facebook apps login (if you don’t put the iframe option, you’re going to run into the “Redirect to Facebook” problem). And obviously, depending on the login Strategy, the redirection will be different after the login.

The solution

I’ve created an omniauth.rb initializer like this one:

# initializers/omniauth.rb

module OmniAuth::Strategies

  class FacebookApp1 < Facebook
    def name 
      :facebook_app2
    end 
  end

  class FacebookApp2 < Facebook
    def name 
      :facebook_app2
    end 
  end

end

Then edit your devise.rb to reflect the new Facebook apps:

# initializers/devise.rb

config.omniauth :facebook, [APP_ID], [APP_SECRET]
config.omniauth :facebook_app1, [APP_ID], [APP_SECRET], :iframe => true, :scope => 'publish_stream,offline_access,email'
config.omniauth :facebook_app2, [APP_ID], [APP_SECRET], :iframe => true, :scope => 'publish_stream,offline_access,email'

 

Finally, make sure that you have one callback method per new Strategy:

# users/omniauthCallbacks.rb

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def facebook
    @user = User.find_for_facebook_oauth(env["omniauth.auth"], current_user)

    if @user.persisted?
      flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Facebook"
      sign_in_and_redirect @user, :event => :authentication
    else
      session["devise.facebook_data"] = env["omniauth.auth"]
      redirect_to new_user_registration_url
    end
  end

  def facebook_app1

    @user = User.find_for_facebook_oauth(env["omniauth.auth"], current_user)

    if @user.persisted?
      flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Facebook"
      sign_in @user, :event => :authentication

      redirect_to "[FACEBOOK_APP1_URL]"
    else
      session["devise.facebook_data"] = env["omniauth.auth"]
      redirect_to new_user_registration_url
    end
  end

  def facebook_app2

    @user = User.find_for_facebook_oauth(env["omniauth.auth"], current_user)

    if @user.persisted?
      flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Facebook"
      sign_in @user, :event => :authentication

      redirect_to "[FACEBOOK_APP2_URL]"
    else
      session["devise.facebook_data"] = env["omniauth.auth"]
      redirect_to new_user_registration_url
    end
  end

end

And now you should be able to login using:

= link_to "Main login with Facebook", user_omniauth_authorize_path(:facebook)

= link_to "Login inside Facebook APP 1", user_omniauth_authorize_path(:facebook_app1)

= link_to "Login inside Facebook APP 2", user_omniauth_authorize_path(:facebook_app2)

Let me know if it has been useful ;)

Thanks for reading. To continue the discussion contact me: or

Do you need a team to build your web/mobile app? Are you looking for some great Ruby on Rails developers?
Send us an email now at hello@cookieshq.co.uk

Related posts