Skip to content

Instantly share code, notes, and snippets.

@Artur-Sulej
Created May 11, 2016 09:26
Show Gist options
  • Save Artur-Sulej/d8bdf88ae8be45610fe79c4261db4144 to your computer and use it in GitHub Desktop.
Save Artur-Sulej/d8bdf88ae8be45610fe79c4261db4144 to your computer and use it in GitHub Desktop.
Module for signing in users with Facebook. It uses Koala gem to access Graph API. It is meant to be used with devise_token_auth gem. Code parially comes from OmniauthCallbacksController class (from devise_token_auth).
module FacebookLoginHelper
def login_with_facebook
return unless fetch_fb_profile
setup_user_by_fb
create_token_info
set_token_on_user
if User.devise_modules.include?(:confirmable)
@user.skip_confirmation!
end
sign_in(:user, @user, store: false, bypass: false)
@user.save!
# Code for storing data from params needed for sending push notifications can be injected here:
yield @user
set_auth_header
status = @oauth_registration ? :created : :ok
respond({json: @user.as_json, status: status})
end
def fetch_fb_profile
graph = Koala::Facebook::API.new(fb_access_token)
begin
@fb_profile = graph.get_object('me', fields: ['name', 'email'])
rescue Koala::Facebook::AuthenticationError
login_failure('Invalid or expired access token.')
return false
rescue Faraday::ConnectionFailed
login_failure('Connection problem.')
return false
rescue
login_failure('Some problem occurred.')
return false
end
unless @fb_profile
login_failure('No such FB profile.')
return false
end
true
end
private
def login_failure(msg)
respond({json: {errors: [msg]}, status: 401})
end
def set_auth_header
auth_header = @user.build_auth_header(@token, @client_id)
response.headers.merge!(auth_header)
end
def fb_access_token
params[:access_token]
end
def setup_user_by_fb
@user = User.where(
{
uid: @fb_profile['id'],
provider: 'facebook'
}).first_or_initialize
if @user.new_record?
@oauth_registration = true
set_random_password
set_generated_nickname
end
set_email_from_fb
@user
end
def set_email_from_fb
email = @fb_profile['email']
@user.email = email if email
end
def set_generated_nickname
fb_name = @fb_profile['name'].gsub(' ', '')
if User.where(nickname: fb_name).empty?
@user.nickname = fb_name
else
@user.nickname = fb_name + SecureRandom.hex(5)
end
end
def set_random_password
password = SecureRandom.urlsafe_base64(nil, false)
@user.password = password
@user.password_confirmation = password
end
def create_token_info
@client_id = SecureRandom.urlsafe_base64(nil, false)
@token = SecureRandom.urlsafe_base64(nil, false)
@expiry = (Time.now + DeviseTokenAuth.token_lifespan).to_i
end
def set_token_on_user
@user.tokens[@client_id] = {
token: BCrypt::Password.create(@token),
expiry: @expiry
}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment