Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3 using Devise: How to allow someone to log in using their Facebook account?

I have a Rails 3 application using Devise for authentication. Now I need to allow someone to log in using their Facebook account. I think this is called Facebook Connect, but I've also heard the term Facebook Graph API, so I'm not sure which one I'm asking for.

What do I need to do in order to integrate Facebook Connect with Devise?

Solution:

This question is pretty old now. A year ago, Devise v1.2 introduced OmniAuth support. Now Devise is at v2.1 (as of this writing) and using OmniAuth is even easier. Here is a great tutorial from the Devise wiki on using the omniauth-facebook gem with Devise to allow sign-in using Facebook.

Also check out this great tutorial on registering your application and working with the Facebook Graph API.

like image 832
Andrew Avatar asked Aug 27 '10 00:08

Andrew


7 Answers

I checked the devise github page to see what they were up to. That project is moving pretty fast and as it happens they have support for facebook connect amongst other things. Check out the section on OAuth2. They use github as an example but it would be the same thing for facebook and they mention differences. I think this is the way to go, third party gems for devise don't move as fast as devise or rails do. Cheers.

Oops here's the link http://github.com/plataformatec/devise

Edit

Of course I did very little coding here mostly went with the default, so here goes:

Create a new app and add these gems to the gemfile.

gem 'devise', :git => 'git://github.com/plataformatec/devise.git'
gem 'oauth2', :git => 'git://github.com/intridea/oauth2.git'

Run bundle install, then these commands gets you going with a basic User authentication model.

rails generate devise:install
rails generate devise User

In config/initializers/devise.rb uncomment/modify these. Look at the last paragraph as to where you get app_key and secret from facebook.

config.oauth :facebook, 'app_key', 'secret',
    :site              => 'https://graph.facebook.com',
    :authorize_path    => '/oauth/authorize',
    :access_token_path => '/oauth/access_token'

This should be your user model.

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :confirmable, :lockable, :timeoutable and :oauthable
  devise :database_authenticatable, :oauthable

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :password_confirmation, :remember_me

  def self.find_for_facebook_oauth(access_token, signed_in_resource=nil)
    # Get the user email info from Facebook for sign up
    # You'll have to figure this part out from the json you get back
    data = ActiveSupport::JSON.decode(access_token)

    if user = User.find_by_email(data["email"])
      user
    else
      # Create an user with a stub password.
      User.create!(:name => data["name"], :email => data["email"], :password => Devise.friendly_token)
    end
  end
end

Devise uses a root :to => "something#here" so I created a home controller with a index action and used that to root the application. But nevermind that. I put that in layout/application.html.erb so that I had basic sign_n sign_out routes.

<span>
  <%- if user_signed_in? %>
    <%= "Signed in as #{current_user.full_name}. Not you?" %>
    <%= link_to 'Sign out', destroy_user_session_path %>
  <%- else %>
    <%= link_to 'Sign in', new_user_session_path %>
  <%- end %>
</span>

Devise pretty much takes care of everything else for us. What you do need to do though is get your app_key and secret from facebook (used in devise.rb config file). This link should get you going. http://developers.facebook.com/setup

like image 188
Hugo Avatar answered Oct 01 '22 10:10

Hugo


Devise 1.2 now comes with facebook login support using omniauth and works with Rails 3.0. Check out the wiki entry.

like image 37
Yeameen Avatar answered Oct 01 '22 11:10

Yeameen


In my app, I use omniauth, which I think came out a bit after this question was answered.

https://github.com/intridea/omniauth

like image 39
alvin Avatar answered Oct 01 '22 11:10

alvin


This blog post did it for me. Give it a look.

like image 27
mikewilliamson Avatar answered Oct 01 '22 11:10

mikewilliamson


Just used Hugo solution with almost no problem. Here is the User.rb code I had to use :

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :confirmable, :lockable, :timeoutable and :oauthable
  devise :database_authenticatable, :oauthable

  # Setup accessible (or protected) attributes for your model
  attr_accessible :name, :email, :password, :password_confirmation, :remember_me

  def self.find_for_facebook_oauth(access_token, signed_in_resource=nil)
    # Get the user email info from Facebook for sign up
    # You'll have to figure this part out from the json you get back

    data = ActiveSupport::JSON.decode(access_token.get('https://graph.facebook.com/me?'))

    logger.info("received from Facebook: #{data.inspect}")

    if user = User.find_by_email(data["email"])
      user
    else
      # Create an user with a stub password.
      User.create!(:name => data["name"], :email => data["email"], :password => Devise.friendly_token)
    end
  end
end

The things changed in this code :

  • name is in attr_accessible (don't forget to add a name field to user)
  • changed JSON decoding
like image 34
Chris Avatar answered Oct 01 '22 11:10

Chris


http://github.com/grimen/devise_facebook_connectable

This gem on github is quite straightforward. Worth a shot!

like image 35
morcutt Avatar answered Oct 01 '22 10:10

morcutt


Here is a small application with integrates with Devise + Twitter + Facebook + Linkedin + Google + Github. All in one place.

You can find source here and a demo here

like image 38
Mohit Jain Avatar answered Oct 01 '22 11:10

Mohit Jain