Facebook Connect which allows you to integrate Facebook into your own sites allowing authentication, registration, friend connecting, and Facebook feed posting in the context of your application.
This tutorial is about integrating facebook connect option in our application using facebooker gem and with basic authentication plugin restful_authentication.
Setup your Facebook Application page. Go to this page, and enter create your application.
Make note of Application ID, API Key, and Secret. You need it for facebooker.yml later.
Callback URL. They refer to a web page a user will be taken to after logging into and logging out of Facebook account. For development I used, I used “http://127.0.0.1:3000/”
I also used the same URL (http://127.0.0.1:3000) for Canvas Callback URL in Canvas section and Connect URL in Connect section.
Now we finished the app creation in facebook site.
Then install the facebooker either as plugin or gem.
ruby script/plugin install git://github.com/mmangino/facebooker.git (or) gem install facebooker
Create a yml file under config folder of your application and name it as facebooker.yml
development: api_key: [Your KEY] secret_key: [Your KEY] callback_url: http://127.0.0.1:3000/ pretty_errors: true set_asset_host_to_callback_url: false tunnel: public_host_username: public_host: public_port: 4007 local_port: 3000 server_alive_interval: 0 production: api_key: [Your KEY] secret_key: [Your KEY] callback_url: http://www.facebook-connect-demo.com set_asset_host_to_callback_url: false tunnel: public_host_username: public_host: public_port: 4007 local_port: 3000 server_alive_interval: 0
Now we need to create a cross-domain receiver file for Facebook Connect to callback on. Luckily, facebooker can do that for us,but make sure you have configured your facebooker.yml file correctly, or the generator will bomb out:
ruby script/generate xd_receiver
Prepare the database. Add two fields to store facebook id and hashed email so that later we can find a user by either one of the two fields.
ruby script/generate migration AddFbsToUser def self.up add_column :users, :fb_id, :integer add_column :users, :email_hash, :string end def self.down remove_column :users, :fb_id remove_column :users, :email_hash end
Run the migration
rake db:migrate
Add the following two lines right after tag in app/views/layouts/application.html.erb.
<%= fb_connect_javascript_tag %> <%= init_fb_connect "XFBML"%>
Also add the followings in the ApplicationController in app/controller/application_controller.rb. When user logs into Facebook account, :facebook_session will have all the information about the user. :facebook_session is utilized a lot.
before_filter :set_facebook_session helper_method :facebook_session
Also in ApplicationController, where I see if a user is logged in or not, I had to put additional code to see if it’s a facebook user. It’s a facebook user, if facebook_session is successfully created.
def fetch_logged_in_user if facebook_session @current_user = User.find_by_fb_user(facebook_session.user) else return unless session[:user_id] @current_user = User.find_by_id(session[:user_id]) end end
Now you can put the following line anywhere in a view, and you will get “Facebook Connect button”.
<%= fb_login_button('window.location = "/users/link_user_accounts";')%>
And it will result something link this:
When a user clicks on the button, it will bring up a popup window where user can log in. After the user is logged in, link_user_accounts action in user controller will either create a new user with Facebook credentials or recognize a user as existing user by either email hash code or facebook user id. It will be covered later.
And also make sure the following line is added to the routes in config/routes.rb.
map.resources :users, :collection => {:link_user_accounts => :get}
In User model in app/models/user.rb.
after_create :register_user_to_fb #find the user in the database, first by the facebook user id and if that fails through the email hash def self.find_by_fb_user(fb_user) User.find_by_fb_id(fb_user.uid) || User.find_by_email_hash(fb_user.email_hashes) end #Take the data returned from facebook and create a new user from it. #We don't get the email from Facebook and because a facebooker can only login through Connect we just generate a unique login name for them. #If you were using username to display to people you might want to get them to select one after registering through Facebook Connect def self.create_from_fb_connect(fb_user) new_facebooker = User.new(:username => "fb_#{fb_user.uid}", :password => "", :email => "") new_facebooker.fb_id = fb_user.uid.to_i #We need to save without validations new_facebooker.save(false) new_facebooker.register_user_to_fb end #We are going to connect this user object with a facebook id. But only ever one account. def link_fb_connect(fb_id) unless fb_id.nil? #check for existing account existing_fb_user = User.find_by_fb_id(fb_id) #unlink the existing account unless existing_fb_user.nil? existing_fb_user.fb_id = nil existing_fb_user.save(false) end #link the new one self.fb_id = fb_id save(false) end end #The Facebook registers user method is going to send the users email hash and our account id to Facebook #We need this so Facebook can find friends on our local application even if they have not connect through connect #We hen use the email hash in the database to later identify a user from Facebook with a local user def register_user_to_fb users = {:email => email, :account_id => id} Facebooker::User.register([users]) self.email_hash = Facebooker::User.hash_email(email) save(false) end def facebook_user? return !fb_id.nil? && fb_id > 0 end
Add the followings in the User controller in app/controller/users_controller.rb.
def link_user_accounts if @current_user.nil? #register with fb User.create_from_fb_connect(facebook_session.user) user = User.find_by_fb_user(facebook_session.user) redirect_to edit_user_path(user) else #connect accounts @current_user.link_fb_connect(facebook_session.user.id) unless @current_user.fb_id == facebook_session.user.id redirect_to playgrounds_path end end
Finally we need to have somewhere to go after login. Let’s create a home page under Users controller users/home.html.erb
<% if logged_in? %> <h2>You are logged in as <%= current_user.name %></h2> <% if current_user.facebook_user? %> <fb:profile-pic uid="<%= current_user.fb_user_id%>" facebook-logo="true" size="thumb" ></fb:profile-pic> <p><a href="#" onclick='FB.Connect.logoutAndRedirect("/logout")'>Logout</a></p> <% else %> <p>why don't you connect with your facebook account</p> <%= fb_login_button('window.location = "/users/link_user_accounts";')%> <p><%= link_to 'Logout', logout_path%></p> <% end %> <% else %> <h2>You are not logged in!</h2> <p><%= link_to 'Signup', signup_path%> or <%= link_to 'Login', login_path%></p> <% end %>
And map it to root and delete public/index.html
map.root :controller => "users", :action => "home"
Everything is ready now. Click on the Connect button and it will redirect you to Facebook.com and return back to our site home page. And our home page will look something like this:
Related Articles