Adding Social Login With OmniAuth

Buy or Subscribe

You can access this course in just a minute, and support my efforts to rid the world of crappy online courses!

Buy Standalone  Subscribe

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