Adding Social Login With OmniAuth

This is a premium course, which you can purchase below.

Buy Now

Social login is imperative for web and mobile applications, so we're going to plug in OmniAuth, allowing our users to authenticate with Google and GitHub.


Bumbled around a bit with this video because I didn't RTFM as I should have. It's critical to read through everything, as there are quite a few moving pieces you need to set up.

The Routes

The first thing to do is to let Devise know about our omniauth controller. In routes.rb, add this:

 devise_for :users,
    controllers: {
      sessions: "users/passwordless",
      omniauth_callbacks: 'users/omniauth_callbacks'
    }

The Controller

The controller itself is reasonably straightforward, but I redid the forwarding paths:

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController

  def github
    # You need to implement the method below in your model (e.g. app/models/user.rb)
    @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: "GitHub") if is_navigational_format?
    else
      session["devise.github_data"] = request.env["omniauth.auth"].except(:extra) # Removing extra as it can overflow some session stores
      redirect_to new_user_session_url
    end
  end

  def failure
    redirect_to root_path
  end
end

The Model

The User model needs a way to find the user, and it's imperative you don't double up on emails!

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :magic_link_authenticatable, :validatable, :rememberable,
    :omniauthable, omniauth_providers: %i[github]

  def is_admin?
    return true if email =="robconery@gmail.com"
  end

  def self.from_omniauth(auth)
    user = User.find_by(email: auth.info.email)
    unless user
      user = User.create!(
        email: auth.info.email,
        provider: auth.provider,
        uid: auth.uid,
        name: auth.info.name
      )
    end
    user
  end

end