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 😉