
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