Humayun Naseer
Humayun Naseer

Reputation: 460

Using omniauth-google-oauth2 in rails API

I'm trying to implement login from google functionality in my Rails API.

I added this line to my device.rb

config.omniauth :google_oauth2, Rails.application.credentials.dig(:google, :google_client_id),
  Rails.application.credentials.dig(:google, :google_client_secret), scope: 'userinfo.email,userinfo.profile' 

I also added client id & secret in my credentials.

Here is my Google function

def google
    @user = User.from_omniauth(request.env["omniauth.auth"])
end

Here is my from_omniauth function from User.rb

def self.from_omniauth(auth)
  where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
    user.provider = auth.provider
    user.uid = auth.uid
    user.email = auth.info.email
    user.password = Devise.friendly_token[0,20]
  end
end

As I'm implementing an API, I don't know should I use request.env["omniauth.auth"] or hardcode the Access-token here I got from OAuthPlayground. If I hardcode the token how can I access the user information from that token?

I'm also using Devise for Authentication in my application, following this tutorial: https://www.digitalocean.com/community/tutorials/how-to-configure-devise-and-omniauth-for-your-rails-application

Upvotes: 2

Views: 8013

Answers (2)

Humayun Naseer
Humayun Naseer

Reputation: 460

Hope you are fine.

Finally, I got the solution as I was confused that how can I fetch the data from the token_id I receive from the front end, as sending name and email from the front end is not the valid way as anyone can change it and can register himself with the wrong name and email.

After this add gem Httparty into your Gemfile.

You will get this token_id from the front-end by google or you can get this by Google-OAuthplayground for testing purposes & can test it by the postman.

Now add Function in users Controller

require 'httparty'                                                             
require 'json'                                                                                                                  
class UsersController < ApplicationController                              
  include HTTParty

     def google_oauth2
       url = "https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=#{params["id_token"]}"                  
       response = HTTParty.get(url)                   
       @user = User.create_user_for_google(response.parsed_response)      
       tokens = @user.create_new_auth_token                      
       @user.save
       render json:@user
     end
    end

or by get user info with access_token you can replace URL with

url = "https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=#{params["access_token"]}"

And add the following function into your User.rb

def self.create_user_for_google(data)                  
  where(uid: data["email"]).first_or_initialize.tap do |user|
    user.provider="google_oauth2"
    user.uid=data["email"]
    user.email=data["email"]
    user.password=Devise.friendly_token[0,20]
    user.password_confirmation=user.password
    user.save!
  end
end  

Now just hit the URL From postman & I hope everything will be working fine. if you have any query just comment, please.

Note: This solution is just for the backend side while Creating Rails API.

Upvotes: 5

Tim Kozak
Tim Kozak

Reputation: 4182

At this point @user = User.from_omniauth(request.env["omniauth.auth"]) after user is created OR found you need to generate JWT access token (for APIs) based on user data or login_user(@user) if you use sessions.

Here is a nice tutorial for JWT if you go with headless rails

or

Here us the link to Device gem that could provide you with login_user(@user) functionality

Video tutorial about oauth

Upvotes: 0

Related Questions