Reputation: 21
How do I use facebook access token on Devise + Omniauth-facebook + Devise_token_auth?
Is there a way to hook the access token into the omniauth-facebook somehow and get the user signed up/logged in? Or any other solution is welcome.
I am able to obtain the access token from facebook graph API on my mobile side.
I've tried to place the access token on the callback url as such: /omniauth/facebook/callback?code=ACCESS_TOKEN but it simply returns {"errors":["Use POST /sign_in to sign in. GET is not supported."]}
I have looked at:
Rails API: Authenticate users from native mobile apps using username/password or facebook token
Suggested solution to look at Warden, but I don't think it needs to be so complicated.
omniauth for rails and ios authentication
Suggested solution is a gem, but the gem is no longer maintained.
Rails Devise OmniAuth Facebook Login from iOS
Suggested solution affected mobile side development, which I'm hoping not to.
Upvotes: 1
Views: 1282
Reputation: 21
I decided to try something and it seems to work.
I've taken codes from @JeremyMoyers here. It's really an ad-hoc solution but it seems to do the trick.
I've overwritten DeviseTokenAuth controller action for omniauth_success:
Routes:
config/routes.rb
namespace :api do
scope :v1 do
# mount_devise_token_auth_for 'User', at: 'auth'
mount_devise_token_auth_for 'User', at: 'auth', controllers: {
omniauth_callbacks: 'omniauth_callbacks',
}
end
end
Controller:
app/controllers/omniauth_callbacks_controller.rb
class OmniauthCallbacksController < DeviseTokenAuth::OmniauthCallbacksController
def omniauth_success
# get_resource_from_auth_hash
# Remove original get_resource_from_auth_hash and implement custom get_resource
get_resource_from_uhash(params[:access_token],params[:expires_in])
create_token_info
set_token_on_resource
create_auth_params
# Skip confirmation is done at custom get_resource
# if resource_class.devise_modules.include?(:confirmable)
# don't send confirmation email!!!
# @resource.skip_confirmation!
# end
sign_in(:user, @resource, store: false, bypass: false)
if @resource.save!
update_auth_header
yield @resource if block_given?
redirect_to @resource
# render_data_or_redirect('deliverCredentials', @auth_params.as_json, @resource.as_json)
else
redirect_to rooth_path
end
end
protected
def get_resource_from_uhash(access_token, expires_in)
graph = Koala::Facebook::API.new(access_token)
profile = graph.get_object('me?fields=email,name,id,picture')
# logger.info(profile)
@resource = User.where({
uid: profile['id'],
provider: 'facebook'
}).first_or_initialize do |user|
user.provider = 'facebook'
user.uid = profile['id']
user.name = profile['name']
user.oauth_token = access_token
user.password = Devise.friendly_token[0,20]
user.image = profile['picture'] if profile['picture'].present?
user.oauth_expires_at = Time.at(expires_in)
user.skip_confirmation!
user.save!
end
if @resource.new_record?
@oauth_registration = true
set_random_password
end
@resource
end
end
Let me know if there are any security concerns for this.
Upvotes: 1