ruby-on-railsfacebookauthlogicfacebookermultiple-accounts

Ruby on Rails: Authlogic Facebook integration: Link accounts with user input instead of automatically using email address


I'm developing a web app in Ruby on Rails. I'm using authlogic to do authentication. My site has its own logins, but I'm hoping to also use Facebook. I tried out authlogic_facebook_connect (using Facebooker). After a lot of hiccups (the docs haven't really been fully kept up), I did get authlogic_facebook_connect to work and it's OK. The default "connect" behavior works perfectly when I'm faced with users who have never used by site before, but it results in a lot of duplicate logins for people that are using different email addresses for Facebook and for my site. Here's what I want:

When the user hits the Facebook "Connect" button (and after they go through the Facebook auth step of clicking 'Allow'), I want a box to pop up asking the user if they want to connect to a pre-existing account on my site or if they want to have an account automatically generated for them.

If they want it automatically generated for them, we're good and we proceed as normal, but if -- on the other hand -- they want to link their Facebook account to an account on my site, I actually want them to enter in their local credentials and find the correct account. In other words, I do not want my solution to automatically figure out which account looks like the right one, I want the user to do this.

Is there any gem / plugin / quick hack that will allow me to pull this off either using authlogic_facebook_connect or OAuth or something else?

--David


Solution

  • Someone else may be able to point you at the perfect gem for this, but I can tell you that I've worked on a similar problem and it wasn't much work to roll our own, based on the oauth2 gem.

    Here's a sketch of the code/flow I use.

    1) User clicks on 'Connect to Facebook' and this sends you to an action like this

    def to_facebook
        options = {
          :redirect_uri => facebook_callback_url,
          :scope => "email,publish_stream" # whatever you want to do
        }
        client = OAuth2::Client.new(FACEBOOK_API_KEY, FACEBOOK_API_SECRET, :site => FACEBOOK_API_SITE)
    
        redirect_to client.web_server.authorize_url(options)
    end
    

    2) User goes over to facebook and gives you all the access you want, then facebook calls the callback you specified facebook_callback_url which should take you to an action like this:

    def facebook_callback
        client = OAuth2::Client.new(FACEBOOK_API_KEY, FACEBOOK_API_SECRET, :site => FACEBOOK_API_SITE)
        access_token = client.web_server.get_access_token(params[:code], :redirect_uri => facebook_callback_url)
    
        do_my_custom_user_association(access_token)
    end
    

    Then you can specify whatever you want in do_my_custom_user_association, you should have a current_user available from authlogic if someone is logged in, so you can redirect to a flow that lets the logged in user select if they want to merge into their current account or a different one. If there's no current user, you can send them to a create account flow, with some facebook data attached.

    Note that this is just a sketch, there are error cases to handle (e.g. facebook_callback will be hit with the param error_reason if the get_acccess_token fails) and I'm not recommending you do all the oauth2 interaction right in your controller, but the basic idea is there.

    See http://developers.facebook.com/docs/authentication/ if any of the oauth2 interactions don't make sense.