Login with Facebook in Rails 6 and Devise.

I can not imagine how it can be stressful when trying to implement third party configuration like Facebook with your application that use devise especially when you get crazy errors.

here i will show you step by step how to login into your application with Facebook using ‘omniauth-facebook’ gem.

First of all you need a Facebook developer account, you can register by visiting:

  • Click on More options
  • then click on something else
  • then add your display app name
  • Complete the security check and this should redirect you to the app(please make sure to turn off add blockers otherwise the security check will not popup).
  • Click on setting then choose basics
  • in the app domains put(localhost).
  • then scroll down to Add platform then choose (‘website’)
  • then type [
  • click on Save changes and save your (app_id and app_secret) for later.

in your Gemfile put:

gem 'omniauth-facebook'
gem 'omniauth'
gem 'omniauth-rails_csrf_protection'

and also change your Devise gem to:

gem 'devise', github: 'heartcombo/devise', branch: 'ca-omniauth-2'

Then we need to add provider and uid strings to the users table so we run:

rails g migration AddOmniauthToUsers provider:string uid:string

then run ‘rake db:migrate’.

Then we need to put our app_id and secret inside rails credentials file so to open it we run:

`EDITOR="code --wait" bin/rails credentials:edit`

note; if you are not using Vscode so change ‘code’ in the above command with your text editor.

Then add:

facebook:
APP_ID: <facebook_app_id>
APP_SECRET: <facebook_app_secret>

and replace them with your APP_ID and APP_SECRET.

Then inside config/initializers/devise.rb put:

config.omniauth :facebook, Rails.application.credentials.facebook[:APP_ID], Rails.application.credentials.facebook[:APP_SECRET], token_params: { parse: :json }

Inside your user Model add :

devise :omniauthable, omniauth_providers: %i[facebook]

and

def self.from_omniauth(auth)
name_split = auth.info.name.split(" ")
user = User.where(email: auth.info.email).first
user ||= User.create!(provider: auth.provider, uid: auth.uid, last_name: name_split[0], first_name: name_split[1], email: auth.info.email, password: Devise.friendly_token[0, 20])
user
end

Then we create a users folder inside app/controllers and inside it create a file called “omniauth_callbacks_controller.rb” and put:

class Users::OmniauthCallbacksController <    Devise::OmniauthCallbacksController
def facebook
@user = User.from_omniauth(request.env["omniauth.auth"])
if @user.persisted?
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"].except(:extra) # Removing extra as it can overflow some session stores
redirect_to new_user_registration_url
end
end
def failure
redirect_to root_path
end
end

Last but not least inside config/routes.rb change “devise_for :users” to:

devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }

Finally inside the views put this:

<%= link_to "Register with Facebook", user_facebook_omniauth_authorize_path, method: :post %>

Note: when you put omniauthable inside the user model it will directly create a link for it and you can see it inside app/views/devise/shared/links, but this link is a get method and it will not work.

if you want to use it just add this line below at the end of the link:

method: :post

in some cases due to security protocol of Facebook you should create an “.env” file in the root of your project and add:

HTTPS = true

and that is all you need to do in order to allow login using Facebook in your application.

Happy Coding:))

Ari Karim

Software developer, I love coding and movies