Skip to content

Instantly share code, notes, and snippets.

@younjiwoo
Last active July 12, 2017 04:55
Show Gist options
  • Save younjiwoo/bf7232803d4701b9b9be80996fa2f81d to your computer and use it in GitHub Desktop.
Save younjiwoo/bf7232803d4701b9b9be80996fa2f81d to your computer and use it in GitHub Desktop.
OmniAuth Gist

OmniAuth

Add Omniauth and Omniauth-Facebook gems.

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.

Create User model.

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

Create Sessions controller

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]

Create Omniauth initializer

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

Add client-side functionality using Javascript

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>

Resources

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment