Skip to content

Instantly share code, notes, and snippets.

@secretpray
Last active May 21, 2021 05:32
Show Gist options
  • Save secretpray/100a66d543d5a61b4f9e82951a1709cc to your computer and use it in GitHub Desktop.
Save secretpray/100a66d543d5a61b4f9e82951a1709cc to your computer and use it in GitHub Desktop.
Add ->
GemFile:
gem 'devise', '~> 4.8'
gem 'omniauth'
gem 'omniauth-facebook'
gem 'omniauth-github'
gem 'omniauth-google-oauth2'
gem 'activerecord-session_store'
gem 'omniauth-rails_csrf_protection'
Edit->
Terminal
EDITOR="atom --wait" rails credentials:edit
facebook:
facebook_client_id:
facebook_client_secret:
github:
github_client_id:
github_client_secret:
google:
google_client_id:
google_client_secret:
Edit&Save, Check -> bin/rails credentials:show
Edit ->
config/initializers/devise.rb
config.omniauth :facebook, Rails.application.credentials.dig(:facebook, :facebook_client_id),
Rails.application.credentials.dig(:facebook, :facebook_client_secret), scope: 'email, public_profile', info_fields: 'first_name, last_name'
config.omniauth :github, Rails.application.credentials.dig(:github, :github_client_id),
Rails.application.credentials.dig(:github, :github_client_secret), scope: 'user.public_repo'
config.omniauth :google_oauth2, Rails.application.credentials.dig(:google, :google_client_id),
Rails.application.credentials.dig(:google, :google_client_secret), scope: 'userinfo.email, userinfo.profile'
Create ->
config/initializers/session_store.rb
Rails.application.config.session_store :active_record_store, key: '_devise-omniauth_session'
Terminal
bin/rails g migration create_sessions
class CreateSessions < ActiveRecord::Migration[6.1]
def change
create_table :sessions do |t|
t.string :session_id, null: false
t.text :data
t.timestamps
end
add_index :sessions, :session_id, unique: true
add_index :sessions, :updated_at
end
end
bin/rails g migration update_users
class UpdateUsers < ActiveRecord::Migration[6.1]
def change
add_column(:users, :provider, :string, limit: 50, null: false, default: '')
add_column(:users, :uid, :string, limit: 500, null: false, default: '')
end
end
bin/rails db:migrate
Add string ->
User.model
devise :database_authenticatable, :registerable,
:recove.... ,
:omniauthable, omniauth_providers:[:facebook, :github, :google_oauth2]
def self.create_from_provider_data(provider_data)
where(provider: provider_data.provider, uid: provider_data.uid).first_or_create do |user|
user.email = provider_data.info.email
user.password = Devise.friendly_token[0, 20] #"XQ3UY34iCcKwL-73SLyL"
end
end
bin/rails g controller omniauth
Add to ->
omniauth_controller.rb
class OmniauthController < Devise::OmniauthCallbacksController
def facebook
@user = User.create_from_provider_data(request.env['omniauth.auth'])
if @user.persisted?
sign_in_and_redirect @user
else
flash[:error] = 'There was a problem signing you in through Facebook. Please register or try signing in later.'
redirect_to new_user_registration_url
end
end
def github
@user = User.create_from_provider_data(request.env['omniauth.auth'])
if @user.persisted?
sign_in_and_redirect @user
else
flash[:error] = 'There was a problem signing you in through Github. Please register or try signing in later.'
redirect_to new_user_registration_url
end
end
def google_oauth2
@user = User.create_from_provider_data(request.env['omniauth.auth'])
if @user.persisted?
sign_in_and_redirect @user
else
flash[:error] = 'There was a problem signing you in through Google. Please register or try signing in later.'
redirect_to new_user_registration_url
end
end
def failure
flash[:error] = 'There was a problem signing you in. Please register or try signing in later.'
redirect_to new_user_registration_url
end
end
config/routes.rb
devise_for :users, controllers: { omniauth_callbacks: 'omniauth' }
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
After refactoring (for multiplay accounts)
bin/rails g model authorization
class Authorization < ApplicationRecord
belongs_to :user
end
+ edit migration
class CreateAuthorizations < ActiveRecord::Migration[6.1]
def change
create_table :authorizations do |t|
t.references :user, foreign_key: true
t.string :provider
t.string :uid
t.timestamps
end
end
end
Remove
bin/rails g migration RemoveColumnsProviderAndUidFromUsers
class RemoveColumnsProviderAndUidFromUsers < ActiveRecord::Migration[6.1]
def change
remove_column :users, :provider
remove_column :users, :uid
end
end
class User < ApplicationRecord
include UserOath
has_many :authorizations, dependent: :destroy
remove old
add
models/concerns/user_oath.rb
module UserOath
extend ActiveSupport::Concern
def create_authorization(auth)
# binding.pry
authorizations.create(provider: auth.provider, uid: auth.uid)
end
def full_name(auth)
if auth.provider == 'facebook' && !auth.info.name.empty?
self.first_name = auth.info.name.split(' ')[0]
self.last_name = auth.info.name.split(' ')[1]
elsif auth.provider == 'google_oauth2'
self.first_name = auth.info.first_name unless auth.info.first_name.empty?
self.last_name = auth.info.last_name unless auth.info.last_name.empty?
end
self.save
end
class_methods do
def find_for_oauth(auth)
authorizations = Authorization.where(provider: auth.provider, uid: auth.uid).first
return authorizations.user if authorizations
email = auth.info[:email]
user = User.where(email: email).first
email ||= create_email(auth) if email.nil?
if user
user.create_authorization(auth)
else
uniq_username = "#{email.split('@')[0]}[#{auth.provider}-#{auth[:uid]}]"
password = Devise.friendly_token[0, 20]
user = User.create!(email: email, username: uniq_username, password: password, password_confirmation: password)
user.full_name(auth)
user.create_authorization(auth)
end
return user
end
def create_email(auth)
"#{auth[:uid]}@#{auth.provider}.com"
end
end
end
new controller
omniauth_callbacks_controller.rb
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
# render json: request.env['omniauth.auth']
@user = User.find_for_oauth(request.env['omniauth.auth'])
if @user.persisted?
sign_in_and_redirect @user
if is_navigational_format?
set_flash_message( :notice, :success, kind: 'Facebook' )
end
else
flash[:alert] = 'There was a problem signing you in through Facebook. Please register or try signing in later.'
redirect_to new_user_registration_url
end
end
def github
@user = User.find_for_oauth(request.env['omniauth.auth'])
if @user.persisted?
sign_in_and_redirect @user
if is_navigational_format?
set_flash_message( :notice, :success, kind: 'Github' )
end
else
flash[:alert] = 'There was a problem signing you in through Github. Please register or try signing in later.'
redirect_to new_user_registration_url
end
end
def google_oauth2
@user = User.find_for_oauth(request.env['omniauth.auth'])
if @user.persisted?
sign_in_and_redirect @user
if is_navigational_format?
set_flash_message( :notice, :success, kind: 'Google' )
end
else
flash[:alert] = 'There was a problem signing you in through Google. Please register or try signing in later.'
redirect_to new_user_registration_url
end
end
def failure
flash[:alert] = 'There was a problem signing you in. Please register or try signing in later.'
redirect_to new_user_registration_url
end
end
routes.rb
devise_for :users, controllers: { omniauth_callbacks: 'omniauth_callbacks', registrations: 'registrations' }
Delete omniauth_controller.rb
Development
===========
Google
------
URIs * http://localhost:3000
Authorized redirect URIs http://localhost:3000/users/auth/google_oauth2/callback
GitHub
------
Homepage URL http://localhost:3000/
Authorization callback URL http://localhost:3000/users/auth/github/callback
Facebook
--------
URL вебсайта: http://localhost:3000/users/auth/facebook/callback/
домен приложения: localhost
Production
==========
Facebook
--------
URL вебсайта: https://recipes-2021.herokuapp.com/users/auth/facebook/callback
домен приложения: recipes-2021.herokuapp.com
"Клиентские настройки OAuth" ("вход через Facebook")
"Действительные URI перенаправления для OAuth":
https://recipes-2021.herokuapp.com/users/auth/facebook/callback/
GitHub
------
Homepage URL: https://recipes-2021.herokuapp.com/
Authorization callback URL: https://recipes-2021.herokuapp.com/users/auth/github/callback
Google
------
URIs * https://recipes-2021.herokuapp.com
Authorized redirect URIs https://recipes-2021.herokuapp.com/users/auth/google_oauth2/callback
@secretpray
Copy link
Author

class OmniauthController < Devise::OmniauthCallbacksController

@yshmarov
Copy link

image

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