Introduction
As my coding partner and I are working on our final Rails project, I thought it was a great time to share how we integrated
‘omniauth-facebook’
authentication to our blog app. One way we know to authenticate users is by the use of ‘sessions and cookies’ which is great, but if we wanted our users to sign in with their existing facebook credentials, a third-party service like ‘omniauth-facebook’
is the coolest.What is devise and omniauth-facebook
Devise is a ruby on rails gem which handles all user authentication features in your rails application in a very flexible manner.
Omniauth-facebook on the other hand enables user authentication (login/signup) using their existing facebook account.
In general the Omniauth-provider is a service which enables user authentication through 3rd-party services such as facebook, twitter, google, and so on.
Setting up devise and omniauth-facebook
Build a basic rails application
#create rails project
rails new my-rails-app — database=postgresql
#navigate to project directory
cd my-rails-app
#create database
run rails db:create
run rails db:migrate
Devise gem installation and setup
#generate the pages controller to handle the app home page
rails g controller Pages home
#open config/routes.rb
-set root route
root to: ‘pages#home’
#add devise gem to gemfile
#my-rails-app/Gemfile
gem ‘devise’
run bundle install
rails g devise:install
#set alerts and notices in application.html.erb
run rails g devise:views
run rails g devise User
run rails db:migrate
Omniauth-facebook setup
1. Go to https://developers.facebook.com/ and create facebook developer account
2. add ‘omniauth-facebook’ gem to your gemfile
#my-rails-app/Gemfile
gem ‘omniauth-facebook’
3. Update the User Table with the params needed
run rails g migration AddOmniauthToUsers provider:string uid:string name:string image:text
run rails db:migrate
4. Update initializer
# config/initializers/devise.rb
config.omniauth :facebook, “App ID”, “App Secret”,
callback_url: “http://localhost:3000/auth/facebook/callback"
5. Update the model
# app/models/user.rb
devise :omniauthable, :omniauth_providers => [:facebook]
verify your schema for the additional fields/columns
app/views/pages/home.html.erb
<% unless current_user %>
<%= link_to “Sign in with Facebook”, user_facebook_omniauth_authorize_path %>
<% else %>
<%= link_to “Logout”, destroy_user_session_path, method: :delete %>
<% end %>
# config/routes.rb
devise_for :users, :controllers => { :omniauth_callbacks => “users/omniauth_callbacks” }
6. Create a users directory
mkdir app/controllers/users
7. Create a users controller with the following omniauth methods
# app/controller/users/omniauth_callbacks_controller.rb
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
set_flash_message(:notice, :success, :kind => “Facebook”) if is_navigational_format?
else
session[“devise.facebook_data”] = request.env[“omniauth.auth”]
redirect_to new_user_registration_url
end
end
def failure
redirect_to root_path
end
end
8. Add custom methods to the User model
# app/models/user.rb
def self.new_with_session(params, session)
super.tap do |user|
if data = session[“devise.facebook_data”] && session[“devise.facebook_data”][“extra”][“raw_info”]
user.email = data[“email”] if user.email.blank?
end
end
end
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
user.name = auth.info.name # assuming the user model has a name
user.image = auth.info.image # assuming the user model has an image
end
end
REFERENCES