Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

devise token auth + Save Facebook info

I am using Devise auth token gem and ng-token auth for authenticating my single page app. Besides registering with email there is the option to sign-up via Facebook. It works.

My problem is that as for my Fb request scope I set to get the user_friends, email and public_info, however when I get the request I don't see the auth_hash request.env['omniauth.auth']. This is described in the omniauth-facebook gem documentation.

Basically I want to save what FB gives back about the user in my database. How would you do it?

like image 803
Gustavo Guimaraes Avatar asked Nov 09 '22 07:11

Gustavo Guimaraes


1 Answers

I use this end-point with Ionic2 app, for Facebook Login requests on Rails 5 API, using Koala and Devise Token Auth so you should be able to replicate on any Rails 5 app:

def facebook
  @graph = Koala::Facebook::API.new(oauth_params[:token], ENV["FACEBOOK_SECRET"])
  @profile = @graph.get_object("me?fields=email,first_name,last_name,picture.type(large)")

  unless @user = User.where(email: @profile["email"])&.first
    @user = User.new(email: @profile["email"])
  end
  #
  # Here you will make your logic for saving Facebook's data on your User model,
  # customize accordingly
  #
  if @user.new_record?
    p = SecureRandom.urlsafe_base64(nil, false)
    @user.password = p
    @user.password_confirmation = p
    #
    # "Passwordless" login, user must set password after registering,
    # or be forever haunted by indecipherable SecureRandom value
    #
    @user.name = @profile["first_name"]+ " " + @profile["last_name"]
    @user.remote_avatar_url = @profile["picture"]["data"]["url"]
    @user.confirmed_at = Time.now
    @user.uid = @profile["id"]
    @user.provider = 'Facebook'
  end

  @client_id = SecureRandom.urlsafe_base64(nil, false)
  @token     = SecureRandom.urlsafe_base64(nil, false)
  @user.tokens[@client_id] = {
    token: BCrypt::Password.create(@token),
    expiry: (Time.now + DeviseTokenAuth.token_lifespan).to_i
  } 
  auth_header = @user.build_auth_header(@token, @client_id)
  # update the response header
  response.headers.merge!(auth_header)
  @user.save!
  if sign_in(:user, @user, store: false, bypass: false)
    render json:  {
      data: @user.token_validation_response 
    }
  end
end

Point a POST route to this and pass authResponse.accessToken from Facebook request as params[:token]. Voilà, authentication magic!

like image 189
ErvalhouS Avatar answered Nov 15 '22 06:11

ErvalhouS