Skip to content

Instantly share code, notes, and snippets.

@nicoolas25
Created October 29, 2013 16:15
Show Gist options
  • Save nicoolas25/7217758 to your computer and use it in GitHub Desktop.
Save nicoolas25/7217758 to your computer and use it in GitHub Desktop.
Rails 4 + Devise 3 + (google | windows live | facebook) Oauth2
# config/initializers/devise.rb
Devise.setup do |config|
# ...
require 'omniauth-google-oauth2'
require 'omniauth-windowslive'
require "omniauth-facebook"
config.omniauth :google_oauth2, Settings[:google]['app_id'], Settings[:google]['app_secret'], { access_type: "offline", approval_prompt: "" }
config.omniauth :windowslive, Settings[:windowslive]['app_id'], Settings[:windowslive]['app_secret'], { scope: 'wl.basic,wl.emails' }
config.omniauth :facebook, Settings[:facebook]['app_id'], Settings[:facebook]['app_secret']
# ...
end
gem 'devise'
gem 'omniauth'
gem 'omniauth-facebook'
gem 'omniauth-google-oauth2'
gem 'omniauth-windowslive'
# app/controllers/devise_users/omniauth_callbacks_controller.rb
class DeviseUsers::OmniauthCallbacksController < Devise::OmniauthCallbacksController
PROVIDER_KIND_NAMES = {
google_oauth2: 'Google',
windowslive: 'Windows Live',
facebook: 'Facebook'
}.freeze
User::OAUTH_INFOS.keys.each do |provider|
kind_name = PROVIDER_KIND_NAMES[provider]
class_eval %Q"
def #{provider}
@user = User.find_for_#{provider}(request.env['omniauth.auth'], current_user)
if @user.persisted?
flash[:notice] = I18n.t 'devise.omniauth_callbacks.success', kind: '#{kind_name}'
sign_in_and_redirect @user, event: :authentication
else
flash[:alert] = I18n.t 'devise.omniauth_callbacks.failure', kind: '#{kind_name}', reason: @user.errors.full_messages
redirect_to new_user_registration_url
end
end
"
end
end
# app/models/user.rb
class User # < YourORM::Base
# Don't forget the other devise modules
devise :omniauthable, omniauth_providers: [:google_oauth2, :windowslive, :facebook]
OAUTH_INFOS = {
google_oauth2: {
email: 'data.info.email',
first_name: 'data.info.first_name',
last_name: 'data.info.last_name'
}.freeze,
windowslive: {
email: 'data.extra.raw_info.emails.preferred',
first_name: 'data.extra.raw_info.first_name',
last_name: 'data.extra.raw_info.last_name'
}.freeze,
facebook: {
email: 'data.info.email',
first_name: 'data.info.first_name',
last_name: 'data.info.last_name'
}.freeze
}.freeze
class << self
OAUTH_INFOS.each do |provider, infos|
class_eval %Q"
def find_for_#{provider}(data, signed_in_resource=nil)
where(email: #{infos[:email]}).first_or_create do |u|
u.provider = '#{provider}'
u.first_name = #{infos[:first_name]}.presence || 'John'
u.last_name = #{infos[:last_name]}.presence || 'Do'
u.password = Devise.friendly_token[0,20]
end
end
"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment