Authentication with Google Sign-In is a common practice in modern applications. In this blog post, we will discuss how to integrate Google Identity Services into any of your front-end applications that use Ruby on Rails as the server. Google Identity Services provides with

  1. Customized Sign In/Sign Up Button

One Tap Sign In

Let's dive in!!

Step 1: Create an application in the Google Developer Console.

In order to use Google Sign In or One Tap, we need a client_id to add in our client as well server.

For more details on setting up the application, you can read here.

Step 2: Setting up the Library in Client

In order to load the client library, add <script src="https://accounts.google.com/gsi/client" async defer></script> in your index.html if you are using React.js or _app.jsx if using Next.js.

Step 3: Displaying the customized Sign In Button

  useEffect(() => {
    /* global google */
    google.accounts.id.initialize({
      client_id:
        "YOUR_GOOGLE_CLIENT_ID",
      callback: signInCallback,
      cancel_on_tap_outside: false,
    });

    google.accounts.id.renderButton(document.getElementById("signInDiv"), {
      theme: "outline",
      size: "large",
    });
  }, []);

return (
    <div className="App">
      <div id="signInDiv" />
    </div>
);

you will be able to see a customized button like this

Step 4: Displaying the One Tap Prompt

Step 5: Defining the callback function

const signInCallback = (result) => {
  if (result.credential) {
    const params = { token: result.credential };
    axios
      .post("http://localhost:3000/user/google", params)
      .then((res) => {
        const { authToken, ...userInfo } = res.data.data;
        // set token in local storage/cookies based on your authentication method
        // redirect to the authenticated page
       })
       .catch((err) => console.log(err));
   }
};


where,

Step 6: Adding the controller & route to Server

We will create a route in the server to handle the request from the client. Before we do that, we need to create a controller that will accept the JWT from the client.

Google::Auth::IDTokens.verify_oidc access_token, aud: "YOUR_GOOGLE_CLIENT_ID"

where access_token is the JWT received from the client & aud is a google application client id.

{
  "iss": "https://accounts.google.com",
  "nbf": 12345678,
  "aud": "YOUR_GOOGLE_CLIENT_ID,
  "sub": "1112223333444",
  "email": "[email protected]",
  "email_verified": true,
  "azp": "YOUR_GOOGLE_CLIENT_ID",
  "name": "First Last",
  "picture": "https://lh3.googleusercontent.com/a/AItbvmnvsIQFJw",
  "given_name": "First",
  "family_name": "Last",
  "iat": 1653797115,
  "exp": 1653805725,
  "jti": "8ffa19190gngd46745ff558821f953802"
}

# users/user_controller.rb
def google
  begin
    data = Google::Auth::IDTokens.verify_oidc access_token, aud: "YOUR_GOOGLE_CLIENT_ID"
    // find the user in the data
    // if the user does not exist, create a user using data
    // sign the user (based on your authentication method)
  rescue StandardError => e
  end
end

# config/routes.rb

scope :user do
  post 'google' => 'users#user_controller.rb'
end

PS: Make sure to have rack-cors installed on your server and add this application.rb

config.middleware.insert_before 0, Rack::Cors do
      allow do
        origins '*'
        resource(
          '*',
          headers: :any,
          expose: ['Authorization'],
          methods: %i[get patch put delete post options show]
        )
      end
    end

to avoid facing errors like this

PPS: If your application uses the Google Sign-In JavaScript Platform Library for the web, make sure to migrate it to Google Identity Service since the former is going to be deprecated. Link

I hope this article helps you integrate One Tap Login into your projects. For more detailed information you can check out the official docs.

Also Published here