To integrate Facebook signup and login in your application you need to do the followings.
in your Gemfile
Generate a migration to add to needed fields in your user model
rails g migration AddUidProviderToUser uid:string provider:string
You need to have an App in your Facebook developer
Go to Facebook Developers
Create a new App in right side of this page Under My Apps
Go to the newly created app, there you’ll see a sidebar on left
Click on Settings Tab from there you need to copy the APP_ID and APP_SECRET.
Paste these value in ‘config/initializers/devise.rb‘ like this
config.omniauth :facebook, 'YOUR_APP_ID', 'APP_SECRET', scope: 'email,public_profile, user_likes,user_education_history, user_about_me,user_birthday,user_hometown,user_friends', info_fields: 'email,id,name,first_name,last_name,age_range,link,gender,timezone,updated_time,verified,friends,hometown,location,birthday,education,work,likes', callback_url: "http://www.localhost:3000/users/auth/facebook/callback", secure_image_url: true, image_size: 'large'
NOTE- READ this link https://developers.facebook.com/docs/facebook-login/permissions for Facebook scope permissions.
In the same “Settings Tab” you need to set two other options which are
App Domains, which will be ‘localhost‘ when you are on your local machine and IF you’re deploying your App to some other host then you need to copy that host in domains.
Then click on “Add Platform” button below and add a website url, so same rule applies here that if you’re on localhost then paste this ‘http://localhost:3000/‘ and other host if not on localhost.
TO ALLOW PUBLIC TO LOG IN OR SIGNUP USING FACEBOOK YOU NEED TO MAKE YOUR APP PUBLIC
To do that Go to “App Review” Tab change the switch “Make ‘YOUR APPLICATION NAME’ public”
CREATE a controller app/controllers/users/omniauth_callbacks_controller.rb
This is available if you already customized devise controllers in this controller you need to override def facebook method… here you can override other omniauth provider callbacks like GitHub Google etc.
Here the code snippet for Facebook
def facebook if request.env["omniauth.auth"].info.email.blank? redirect_to "/users/auth/facebook?auth_type=rerequest&scope=email" end #we need to define this method in User model -- more info below @user = User.create_from_omniauth(request.env["omniauth.auth"]) if @user.persisted? # redirecting to some path if user is signing in for the very first time redirect_to some_welocme_page_path and return if @user.sign_in_count == 0 sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format? else session["devise.facebook_data"] = request.env["omniauth.auth"] # If facebook auth fails for some reasons redirect him to default devise registration page redirect_to new_user_registration_url end end def failure flash[:notice] = "Trying to get non existent data from facebook which is either not allowed by user or not available." redirect_to root_path end
5- DEFINE THIS method create_from_omniauth in your model class whatever it is called, usually it’s named as user
# app/model/user.rb def self.create_from_omniauth(fb_user_credentials) #Token is sent by call to gem fb_auth_token = fb_user_credentials.credentials.token # get existing user with same uid and provider(in our case provider will be facebook) @user = User.where(provider: fb_user_credentials.provider, uid: fb_user_credentials.uid).first #If user doesn't exists unless @user.present? user = User.new(email: fb_user_credentials.info.email, password: Devise.friendly_token, first_name: fb_user_credentials.info.first_name, last_name: fb_user_credentials.info.last_name) user.pictures << Picture.create(image: URI.parse(fb_user_credentials.info.image)) user.provider = fb_user_credentials.provider user.uid = fb_user_credentials.uid #save and return new user so we can log him into the system if user.save! return user else # return the existing user and log him in @user end end