Devise << Facebook Connect. IMPORTANT: Not maintained anymore.
Ruby
Switch branches/tags
Pull request Compare This branch is 7 commits ahead of grimen:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
lib
.gitignore
MIT-LICENSE
README.textile
Rakefile
devise_facebook_connectable_light.gemspec

README.textile

DEVISE / FACEBOOK CONNECTABLE

Simplified Facebook connect for Devise.

Warning

This is a simplified version of the original Devise Facebook Connectable that only uses the fbs_<APP_ID> cookie for authentication. It removes the dependency on Facebooker because (at time of writing) there was no working version (in gem form) of Facebooker for Rails3.

Since this is specifically for Rails3, it will only work with Ruby 1.9.x (However the only change that makes this necessary is the use of Object#tap instead of Object#returning.).

There is also no longer any need to generate anything: facebooker.yml is not longer necessary and this version makes limited use of Javascript.

What is Devise?

http://github.com/plataformatec/devise

What is Devise Facebook Connect?

Simple:

A very straightforward Facebook Connect authentication/linking with the ease of Devise and power of Facebooker. If I may say it myself: The easiest way to get a Rails app authorized and connected with Facebook Connect. Authentication in Rails should be straightforward, right? Let’s build awesome web-apps instead of re-inventing the authentication!

Dependencies

You’ll need:

Installation

Gem

Currenly this is gem is only available directly from github and preferable using a Gemfile:

  gem 'devise_facebook_connectable_light', :git => 'git://github.com/gorenje/devise_facebook_connectable.git', :require => 'devise_facebook_connectable'

Dependencies

  gem 'devise'

Setup

Devise: Setup

See Devise documentation for instructions on how to setup Devise.

Also see Facebook on how to setup your Facebook app. See below for more details.

Facebook Connectable: Setup

You’ll need an config/initializers/devise_facebook.rb initializer that looks something like:

  Devise::FacebookConnectable.setup do |config|
    config.api_id    = <Facebook API ID>
    config.api_token = <Facebook API Token>
    config.secret    = <Facebook API Secret>
  end

Facebook Connectable: Migration

Assuming you’re Devise model is ‘User’:

  create_table :users do |t|

    t.facebook_connectable

    ...

  end

…and indexes (optional):

  add_index :users, :facebook_uid, :unique => true

…since this gem does not collect facebook emails, you’ll have to remove the unique index on email:

  add_index :users, :email

…and then don’t forget: $ rake db:migrate.

Facebook Connectable: Model

  class User < ActiveRecord::Base

    devise :facebook_connectable, ...

  end

Note: All modules must be specified on the same line since Devise 1.0.0, otherwise Devise will only load the last call devise [MODULES] – which will cause FacebookConnectable to fail to initialize.

Configuration

Create a Facebook app

..if you haven’t already:

Create Facebook Application

…with settings:

Application settings > Connect > Facebook Connect Settings > Connect URL: http://localhost:3000 (for testing purposes)
Application settings > Advanced > Advanced Settings > Sandbox Mode: Enabled

I18n

Sign in/out link labels, and Flash error messages can be set using I18n:

  en:
    devise:
      sessions:
        facebook_invalid: "Could not sign in. Invalid account."
        facebook_timeout: "Facebook session expired., please sign in again to continue."
        facebook_authenticity_token: "Something went wrong. For security reasons, please sign in again."
        facebook_actions:
          sign_in: "Sign in"
          sign_out: "Sign out"

Note: The usage of :sign_in/:sign_out depends on configuration, e.g. not used for the traditional and default Facebook Connect button.

Usage

In app/views/layouts/application.html.*, something like (showing only the relevant parts), you’ll need to add the Facebook Javascript tag and root tag.

  <html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml">
    <head>
      ...
    </head>
    <body>
      ...
      <%= yield %>
      <%= facebook_root_tag %>
      <%= facebook_javascript_include_tag %>
      ...
    </body>
  </html>

or in Haml:

!!!
%html{ :xmlns => "http://www.w3.org/1999/xhtml", "xml:lang" => :en,  :lang => :en }
  %head
  ...
  %body
    ...
    = yield
    ...
    = facebook_root_tag
    = facebook_javascript_include_tag

Notice that both tags have to appear in the body of the document, not in the head. This is particularly important for the javascript include tag since this depends on the existence of the fb-root div, otherwise it won’t work.

View:

…add the sign in/out (connect) link somewhere – auto-detects scope:

  <%= facebook_link %>

…or with explicit scope:

  <%= facebook_link :customer %>

…or even more explicit, something like:

  <% unless signed_in?(:user) %>
    <%= facebook_sign_in_link :user %>
  <% else %>
    <%= facebook_sign_out_link :user %>
  <% end %>

etc.

Callbacks

Both the sign in/out buttons can be given a Javascript snippet that acts as callback. The defaults are:


<%= facebook_sign_out_link :callback => “window.location.href = ‘#{destroy_session_path(scope)}’;” >
<= facebook_sign_in_link :callback => “window.location.href = ‘#{session_path(scope)}’;” %>

I.e. when the user is logged in, they are redirected to the sessions page that Devise provides. On logout, the user is redirect to the session destroy of Devise. These are important to info Devise that the user either logged in or logged out.

DONE!

  $ rails s

Note: If you experience any issues with connecting and/or signing in/out now, then I simply must have forgot something in these instructions. Please file a GitHub-issue in such case! =)

Important

It’s not been tested extensively. These are changes that I required to get Facebook connect working with Devise using the existing fb:login-button (or the helpers defined here).

It does not do OAuth2 authentication — only cookie based.

References

Documentation:

Repos:

TODO / Known Issues

Priority:

  • Timeoutable module should timeout Facebook sessions as well – configurable.
  • Specs/Features would be great. Skipped tests so far as I built this using experimenting as I wasn’t sure how Devise and Warden was working – trial-n-error style. Would appreciate any help on this. Looking into using Cucumber + watircuke / culerity.
  • Disconnect link helper would makes sense, i.e. disconnect a Facebook account from the app/site (a.k.a. delete the account Facebook Connect style).
  • Connect existing accounts using Connect.registerUsers.
  • Option: Facebooker vs. MiniFB – a more slimmed implementation if Facebooker feels to heavy – for those who don’t want to depend on Facebooker – want something more light-weight. Most probably implemented using MiniFB.
  • Review controller logic – some of my Facebooker hacks in controller might not be best practice. They seem to do the job though. =)

Maybe:

  • Expired sessions aka Facebooker::Session::SessionExpired appears less now after some controller filter hacks – but needs thorough testing.
  • HAML vs ERB clash – that I right now consider as a HAML bug – breaks the view helpers if both ERB and HAML is used in the same project. Can be avoided by either using HAML gem/plugin and use HAML views only, and vice-versa. Note: Something with the form_for-helper causing this issue.

License

Released under the MIT license.
Copyright © 2009-2010 Jonas Grimfelt