By: Anamika Mishra Category: Shopify,Ruby on Rails,E-Commerce Technologies:
In previous days, when people visit a website and want to register on that particular website they need to fill a form containing numbers of fields and there are some verification processes as well, for example, email verification. It is okay with one website but when people want to login on to more than one website than repeating the same process, again and again, becomes tedious and boring.
This can be made easier using third party services which allow users to log in through their social media account. You can integrate any social media sites which allows user authentication through them into your website. In this section, we will see how to integrate facebook’s third-party service into rails application to authenticate the user.
Steps for Facebook Integration in rails application:
Creating Application
Firstly, you must register on the facebook developer account. Visit https://developers.facebook.com to create an account on it or login if you already have an account.
After login, click on My Apps at the top-right and click on Create App.
Enter the Display Name i.e the name which you want to give to an app and Contact Email and click on Create App ID button
After click on Create App ID button application will be created and you will be taken to the setting page. Go to settings --> Basic from the left menu.
In-App domain field enters localhost and enters http://localhost:300 in Site Url.
From the bottom of the page click on Add Platform and choose Website.
Click on Save changes button at the bottom of the page
Select the dashboard from the left menu. Note down the App ID and App Secret key.
Adding Gem
Now, in your rails application in gemfile.rb add :
gem 'devise', '~> 4.2'
gem 'omniauth-facebook', '~> 4.0'
The omniauth
standardizes third party authentication for Rails applications and Devise gem supports integration using omniauth
To install the added gem run:
bundle install
Configuring Devise
Open the file config/initializers/devise.rb
and add the following code and replace
FACEBOOK_APP_ID
and
FACEBOOK_APP_SECRET
with your application
App ID
and
Secret key.
config.omniauth : facebook, ENV['FACEBOOK_APP_ID'],
ENV['FACEBOOK_APP_SECRET'],
callback_url: "http://localhost:3000/users/auth/facebook/callback"
Omniauth strategy is configured in your rails application with the help of config.omniauth
method.
Writing Migrations
Execute the following command from terminal to generate the migration to update user table:
rails generate migration update_users
Open the file
db/migrate/update_users.rb
and add the following code.
class UpdateUsers < ActiveRecord::Migration[5.0]
def change
add_column(:users, :provider, :string, limit: 50, null: false, default: '')
add_column(:users, :uid, :string, limit: 500, null: false, default: '')
end
end
Update Model
The provider
and uid
fields identify a user uniquely as this pair will always have unique values.
Then run :
rails db:migrate
To save the data provided by the third party into your database, we need to create a method in the User model.
Open the file app/models/user.rb
and add the following code.
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:confirmable, :lockable, :timeoutable,
:omniauthable, omniauth_providers: [:facebook, :github, :google_oauth2, :twitter]
def self.create_from_provider_data(provider_data)
where(provider: provider_data.provider, uid: provider_data.uid).first_or_create do | user |
user.email = provider_data.info.email
user.password = Devise.friendly_token[0, 20]
user.skip_confirmation!
end
end
end
Callback controller
Devise works by providing a callback URL for each provider that you use. Generate the Omniauth callback controller and add the facebook callback code in it.
rails generate controller users/omniauth
Facebook callback
def facebook
@user = User.create_from_provider_data(request.env['omniauth.auth'])
if @user.persisted?
sign_in_and_redirect @user
set_flash_message(:notice, :success, kind: 'Facebook') if is_navigational_format?
else
flash[:error] = 'There was a problem signing you in through Facebook. Please register or try signing in later.'
redirect_to new_user_registration_url
end
end
In the request environment i.e request.env['omniauth.auth']
the data provided by the third party is available to our application that is why we have passed it to the create_from_provider_data method we created in user model
Add the failure callback which devise will execute when authentication fails.
def failure
flash[:error] = 'There was a problem signing you in. Please register or try signing in later.'
redirect_to new_user_registration_url
end
Add sign in link
to redirect users to third party applications and to allow them to sign in to our application,
Open the file app/views/devise/shared/_links.html.erb and add the following code.
<%- if devise_mapping.omniauthable? %>
<%- resource_class.omniauth_providers.each do |provider| %>
<%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}",
omniauth_authorize_path(resource_name, provider) %><br />
<% end -%>
<% end -%>
The above code checks your Omniauth setup and generates the required links for login into the rails application.
Add Routes
Add the additional controllers
the
parameter to specify the callbacks controller and will not be present in the route declaration that you have already added.
Rails.application.routes.draw do
.
.
.
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth' }
end
In this way, we can use third party service in rails application with the combined use of Devise and Omniauth gems.