Detailed Guide on Google 0auth Integration React App)

Detailed Guide on Google 0auth Integration React App)

Written by Mayank Ranjan on Dec 20th, 2022 Views Report Post

Google Auth python-based library to integrate the google authentication. It reduces the risk of hacking and requires credentials to log in. Google Oauth offers multiple added benefits to react app developers. They can do any modification by enabling numerous accessibilities to improve user experience.

Here we will follow some steps to integrate Google Authentication:

  • Access to Google Search Console.
  • Manage Configuration for OAuth Consent.
  • React App Deployment.
  • Express Server launch with important file creation.
  • Configure Browser/ Client Side Routing.
  • Hook Integration.
  • Button Authentication and Customization.
  • Managing proper path routes.
  • .env file modification
  • Launch a Landing page, sign-up page, and log-in page.

Success Log-in with Google Search OAuth Configuration

Anyone who wants to launch the accessibilities of Google Auth to their react app must set up a client ID & secret. For this, first, you need to head to the dashboard of google console.

  • Access the tab My first project. 
  • A box will appear on your screen. 
  • Navigate to the item ‘new project.’ 
  • Give an appropriate name to this project and create.

This new project will be updated with all your previous projects. You can select the project from there.

Once you select the screen will display the project on which you’re working: project ID, its number, and quick options to navigate somewhere else.

To manage the configuration of Oauth, navigate to APIs & Services tab/ option. You can access these APIs and services through the menu.

Then explore other options inside it and click on the OAuth consent screen.

Here you can find Internal and external options. Choose the one based on the app's accessibility preferences. How much access do you want to give to your users?

  • In choosing the internal Google OAuth consent screen, react app verification is needed and limited to only organizational users.
  • In case of an external consent screen, the testing mode will begin for anyone available with a google account. The app will be available to access only for the users added to the list. App verification is needed when it is ready to move into production.
  • Confirm this procedure of consent setup.

Now enter the credential detail along with the app details. Your app may be running on localhost. During the deployment phase of the application, launch https://example.com

After confirming the credential details, get access to your client ID and Secret.

Setup/ Integration of Google Oauth with React

First, you should have an app ready or create the new one. They launch a new folder with the appropriate name. 

Proceed with the following code to run the terminal:

npx create-react-app app

Next, we need to launch the Express Server as a server.

On this server, we will head on the terminal and cd as cd server.

Require a file creation assigning a name server.js. It will look something like the following structure:

// server.js
const express = require("express");
const app = express();
require("dotenv/config"); // configure reading from .env
const cors = require("cors");
const { OAuth2Client } = require("google-auth-library");
const jwt = require("jsonwebtoken");

app.use(
  cors({
    origin: ["http://localhost:3000"],
    methods: "GET,POST,PUT,DELETE,OPTIONS",
  })
);
app.use(express.json());

let DB = [];

app.listen("5152", () => console.log("Server running on port 5152"));
  • It’s time to launch package.json.

Type npm init-y to launch package.json.

We need to initiate more packages and files to manage the robust accessibilities essential for web and mobile apps. We need a middleware for various cross-platform resource-sharing actions and environment variables loading. Initiate google-auth library for Node.js, jsonwebtoken library, and a monitor script.

  • Hence, it would be best if you launched Express.js, CORS, .env, googleauthlibrary, Nodemon, and jsonwebtoken.

For this, you need to do a simple thing:

npm install express cors .env google-auth-library jsonwebtoken nodemon

  • A few more lines to manage the script configuration:
// package.json
  "scripts": {
    "start": "node server.js",
    "dev": "nodemon server.js"
},

package.json will appear as follows:

// package.json
{
  "name": "connect-google-auth-article",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "start": "node server.js",
    "dev": "nodemon server.js"
  },
  "dependencies": {
    "cors": "^2.8.5",
    "dotenv": "^16.0.2",
    "express": "^4.18.1",
    "google-auth-library": "^8.5.2",
    "jsonwebtoken": "^8.5.1",
    "nodemon": "^2.0.20"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
  • Done with server creation. Roll out the client app: react app. For this type, this script code in public/ index.html

<script src="https://accounts.google.com/gsi/client" async defer></script>

Create two folders where you will save all the important files. The location will be src by naming screens and hooks.

Home, landing, log-in, sign-up, and the index will store inside the screens folder. All will have the same extension.jsx, only the index file will have js extensions. In the second folder, we have hooks that will store useFetch.jsx file.

  • Client-side Routing Configuration

Here, react-router-dom is a package that initiates the configuration.

Head to the new terminal and cd. Type the following code to initiate the package configuration.

npm install react-router-dom

Add some modifications to the App.js file.

  • Landing Page Creation Design a sample landing page containing the links to two more pages. These links will navigate to the login page and sign up.

We will have an empty tag here to represent the React fragment. 

There are two elements tagged. So the header tag will output h1 by positioning ht text into the center. And the other one is the main. It will take the responsibility to return the react-router-dom links. With the appropriate UX design, you can customize the buttons. 

In the next step, move to the screens/index.js and export this page.

export { default as Landing } from "./Landing";

Head to App.js and import landing here. We need to initialize the route

import { Landing } from "./screens";

<Route
  path="/"
  element={user?.email ? <Navigate to="/home" /> : <Landing />}
  />
  • Access useFetch Hook

Integrate React accessibilities through the hook function.

// useFetch.jsx
import { useState } from "react";

const useFetch = (url) => {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState("");

  const handleGoogle = async (response) => {
    console.log(response)
  };
  return { loading, error, handleGoogle };
};

export default useFetch;
  • Create a sign-up page file inside the screens and add the accurate code. Also, import useEffect, Link, and useFetch.

useFetch: states and functions, URL to manage the server signing-in, callback. 

useEffect: we will look for Google’s script. This will be arranged through a file public.index.html.

We want to manage the button authentication. For this, we will use renderButton. Here we will use getElementById to pass the first parameter. We will use more parameters devoted to button customization, like defining types of icons and standards. We will style the button theme, size, shape, width, logo alignment, and locale. We will figure out the error and loading state.

  • Next, design the log-in page, importing useEffect, Link, and useFetch.
  • Access the root folder, and create the file naming as .env.local

REACT_APP_GOOGLE_CLIENT_ID=your client id

Here, require the export action for the sign-up and log-in page.

Then manage the route configuration in App.js.

// App.js
<Route
    path="/signup"
    element={user?.email ? <Navigate to="/home" /> : <Signup />}
  />
  <Route
    path="/login"
    element={user?.email ? <Navigate to="/home" /> : <Login />}
  />

useFetch file needs some modification. This file you’ll find inside hooks. As we know server call will be executed. We need authenticity verification for a user session. JWT credentials will help to assist the google authentication response.

After making some changes, this useFetch.jsx file will appear like this:

const handleGoogle = async (response) => {
    setLoading(true);
    fetch(url, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },

      body: JSON.stringify({ credential: response.credential }),
    })
      .then((res) => {
        setLoading(false);

        return res.json();
      })
      .then((data) => {
        if (data?.user) {
          localStorage.setItem("user", JSON.stringify(data?.user));
          window.location.reload();
        }

        throw new Error(data?.message || data);
      })
      .catch((error) => {
        setError(error?.message);
      });
  };

Launch routes for the sign-up and log-in page

For this, we need to define the function inside the server.js file. It will play an important role during the google account verification.

// server.js

const GOOGLE_CLIENT_ID = process.env.GOOGLE_CLIENT_ID;
const client = new OAuth2Client(GOOGLE_CLIENT_ID);

async function verifyGoogleToken(token) {
  try {
    const ticket = await client.verifyIdToken({
      idToken: token,
      audience: GOOGLE_CLIENT_ID,
    });
    return { payload: ticket.getPayload() };
  } catch (error) {
    return { error: "Invalid user detected. Please try again" };
  }
}

Add this piece of code to the .env file:

# .env
GOOGLE_CLIENT_ID=your client id
JWT_SECRET=mySecret

Add this piece of code to the .server file. Required for the sign-up route:

// server.js
app.post("/signup", async (req, res) => {
  try {

    if (req.body.credential) {
      const verificationResponse = await verifyGoogleToken(req.body.credential);

      if (verificationResponse.error) {
        return res.status(400).json({
          message: verificationResponse.error,
        });
      }

      const profile = verificationResponse?.payload;

      DB.push(profile);

      res.status(201).json({
        message: "Signup was successful",
        user: {
          firstName: profile?.given_name,
          lastName: profile?.family_name,
          picture: profile?.picture,
          email: profile?.email,
          token: jwt.sign({ email: profile?.email }, "myScret", {
            expiresIn: "1d",
          }),
        },
      });
    }
  } catch (error) {
    res.status(500).json({
      message: "An error occurred. Registration failed.",
    });
  }
});

Add this piece of code to the server.js file. Required for the log-in route:

// server.js
app.post("/login", async (req, res) => {
  try {
    if (req.body.credential) {
      const verificationResponse = await verifyGoogleToken(req.body.credential);
      if (verificationResponse.error) {
        return res.status(400).json({
          message: verificationResponse.error,
        });
      }

      const profile = verificationResponse?.payload;

      const existsInDB = DB.find((person) => person?.email === profile?.email);

      if (!existsInDB) {
        return res.status(400).json({
          message: "You are not registered. Please sign up",
        });
      }

      res.status(201).json({
        message: "Login was successful",
        user: {
          firstName: profile?.given_name,
          lastName: profile?.family_name,
          picture: profile?.picture,
          email: profile?.email,
          token: jwt.sign({ email: profile?.email }, process.env.JWT_SECRET, {
            expiresIn: "1d",
          }),
        },
      });
    }
  } catch (error) {
    res.status(500).json({
      message: error?.message || error,
    });
  }
});

Modification practice in App.js

// App.js
 useEffect(() => {
    const theUser = localStorage.getItem("user");

    if (theUser && !theUser.includes("undefined")) {
      setUser(JSON.parse(theUser));
    }
  }, []);

Design a home.jsx page. Users will navigate to this page after making a successful log-in or sign-up action.

Add this code to make an export from the screens/index.js

export { default as Home } from "./Home";

Import all home, landing, log-in, sign up from screens and then initialize the route as follows:

<Route
    path="/home"
    element={user?.email ? <Home user={user} /> : <Navigate to="/" />}
  />

Wrapping Up:

Here we reached an end; we have successfully managed import, routes, and Google Authentication Setup to our React App. I hope it will eliminate all the hurdles disturbing the signup and login. If you also face profile id blocking issues, that will resolve.

Comments (0)