Open up your Gemfile
and add the following gems to it.
gem 'omniauth'
gem 'omniauth-facebook', '1.4.0'
Make sure you run the bundle install
command. This configures your Rails application to use those gems.
We need to generate a User
model and add in some necessary fields that Omniauth uses for user authentication.
Run the following command from terminal:
rails g model User provider uid name oauth_token oauth_expires_at:datetime
Create a method in the User model that interacts with Omniauth's object.
class User < ActiveRecord::Base
def self.from_omniauth(auth)
where(auth.slice(:provider, :uid)).first_or_initialize.tap do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name
user.oauth_token = auth.credentials.token
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
user.save!
end
end
end
Then we need to create a helper method in our ApplicationController
to access whoever is logged in at the moment.
class ApplicationController < ActionController::Base
protect_from_forgery
private
def current_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user
end
Next lets create a sessions
controller to handle callbacks. This is where we'll actually login our users.
class SessionsController < ApplicationController
def create
user = User.from_omniauth(env["omniauth.auth"])
session[:user_id] = user.id
redirect_to root_url
end
def destroy
session[:user_id] = nil
redirect_to root_url
end
end
Create a couple of paths in your routes.rb
file as well. Otherwise your Rails application won't know what controller to use.
match 'auth/:provider/callback', to: 'sessions#create', via: [:get, :post]
match 'auth/failure', to: redirect('/'), via: [:get, :post]
match 'signout', to: 'sessions#destroy', as: 'signout', via: [:get, :post]
We need to create an initializer for Omniauth. Create it in config/initializers/omniauth.rb
.
OmniAuth.config.logger = Rails.logger
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, 'YOUR-APP-ID-HERE', 'YOUR-APP-SECRET-HERE'
end
Create a coffescript file called facebook.js.coffee
.
jQuery ->
$('body').prepend('<div id="fb-root"></div>')
$.ajax
url: "#{window.location.protocol}//connect.facebook.net/en_US/all.js"
dataType: 'script'
cache: true
window.fbAsyncInit = ->
FB.init(appId: 'YOUR-APP-ID', cookie: true)
$('#sign_in').click (e) ->
e.preventDefault()
FB.login (response) ->
window.location = '/auth/facebook/callback' if response.authResponse
$('#sign_out').click (e) ->
FB.getLoginStatus (response) ->
FB.logout() if response.authResponse
true
Showing the logged in user in the View.
In your application.html.erb
file, we'll write in some code to display either a sign in link, or the currently logged in user's name.
<div id="user-widget">
<% if current_user %>
Welcome <strong><%= current_user.name %></strong>!
<%= link_to "Sign out", signout_path, id: "sign_out" %>
<% else %>
<%= link_to "Sign in with Facebook", "/auth/facebook", id: "sign_in" %>
<% end %>
</div>