Created
May 11, 2016 09:26
-
-
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).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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