Please Signin

Welcome to Arun's Blog , By signing in, you'll enjoy a seamless journey and save your preferences

Google OAuth with Nodejs and React

Lets implement Google sign in functionality in a the React application without any external library. I will be using Google OAuth 2.0 and Google apis to integrate it in our NodeJs application and at the end we will be calling our nodejs endpoints from out frontend applications like React, Angular, Vue or our vanilla JavaScript

Google OAuth with Nodejs and React

Table of Content

  • Configure Google Consent Screen
  • Generate Client Id and Client Secret
  • Initialize a Node Js application 
  • Setup .env file
  • Building the Application and Integrate Google Apis
  • Connect with Frontend
  • Lets Break down what actually happens?
  • Source Code 😉

Before i start lets see where we should configure the google consent screen

Check here

Configure Google Consent Screen

  1. Visit the above link
  2. Click on select a project and there click on New Project
  3. Give a project name and create a project
  4.  Now Click on Create Credentials and select OAuth Client Id
  5. Click on Configure Consent Screen
  6. Select External and Create
  7. Fill the required * fields
  8. Click on Save  and Continue
  9. Click on Add or Remove Scopes and Select First two options and click on update
  10. In the next screen click on Add users that you will using for testing purposes
  11. Click an Save and Continue and on the next screen click on back to dashboard
Step 1
Step 1

Step 1

Step 2
Step 2

Step 2

Step 3
Step 3

Step 3

Generate Client Id and Client Secret

  1. Again Click on Create Credentials from top and select OAuth Client Id
  2. Select Web Application
  3. Now follow carefully 
  4. Under Authorized redirect URIs we have to add our node js endpoints that google will use to redirect after a successful signin
  5. let put the value
  6. URIs 1 : http://localhost:8080/api/oauth/google/success
  7. URIs 2 : https://YOUR DOMAIN/api/oauth/google/success [This is for production use and can be skipped] 
  8. Click on Create and you can see out client Id and client secret save it somewhere
Step  4
Step  4

Step  4

Initialize A Node Js Application

  1. Run npm init -y
  2. Create index.js, .env file, routes folder and controller folder
  3. Run npm i express dotenv jsonwebtoken

Setup .env file

1   //.env

2   GOOGLE_CLIENT_ID=YOUR_CLIENT_ID

3   GOOGLE_CLIENT_SECRET=YOUR_CLIENT_SECRET

4   REDIRECT_URI=http://localhost:8080/api/oauth/google/success

5   JWT_SECRET_KEY=YOUR_SECRET_KEY //can be anything

Building the Application and Integrate Google Apis

1   //package.json

2  

3   "type": "module"

4   "scripts" : {

5   "start": "node index"

6   }

7  

8  

1   //Index.js

2  

3   import express from "express";

4   import env from 'dotenv';

5   import { oauthRouter } from "./routes/oauth.route.js";

6  

7   env.config();

8  

9   const server = express();

10  

11   server.use('/api/oauth', oauthRouter);

12  

13   server.listen(8080, () => {

14   console.log('Server listening ...')

15   })

1   // routes/oauth.route.js

2  

3   import { Router } from "express";

4   import { handleGoogleConsentScreen, onSuccessGoogleOAuth, verifyToken, signout } from "../controllers/oauth.controller.js";

5  

6   const oauthRouter = Router();

7  

8   oauthRouter.get('/google', handleGoogleConsentScreen);

9   oauthRouter.get('/google/success', onSuccessGoogleOAuth);

10   oauthRouter.post('/verify/:token', verifyToken);

11   oauthRouter.get('/signout', signout);

12  

13   export { oauthRouter }

1   /*

2   * **** Processes involved in implementation of Google OAuth ****

3   *

4   * Configure consent screen and get Client Id and Client Secret

5   * Check: https://console.cloud.google.com/apis/credentials

6   *

7   * Creating google consent screen url with client id

8   * Google redirects the provided redirect uri with a code in params

9   * Getting access_token and id_token form google apis using the code

10   * Getting user details using the access token and token id

11   */

12  

13   import jwt from 'jsonwebtoken';

14  

15   //This funchtion will handle to show google consent screen

16   const handleGoogleConsentScreen = async (req, res) => {

17  

18   const url = new URL('https://accounts.google.com/o/oauth2/v2/auth');

19  

20   const options = {

21   redirect_uri: process.env.REDIRECT_URI,

22   client_id: process.env.GOOGLE_CLIENT_ID,

23   access_type: 'offline',

24   response_type: 'code',

25   prompt: 'consent',

26   scope: [

27   'https://www.googleapis.com/auth/userinfo.profile',

28   'https://www.googleapis.com/auth/userinfo.email',

29   ].join(' ')

30   }

31  

32   url.search = new URLSearchParams(options);

33  

34   return res.redirect(url);

35   }

36  

37   const getGoogleAccessTokens = async (code) => {

38   const url = new URL('https://oauth2.googleapis.com/token');

39  

40   const tokenExchangeOptions = {

41   code,

42   client_id: process.env.GOOGLE_CLIENT_ID,

43   client_secret: process.env.GOOGLE_CLIENT_SECRET,

44   redirect_uri: process.env.REDIRECT_URI,

45   grant_type: 'authorization_code',

46   }

47  

48   url.search = new URLSearchParams(tokenExchangeOptions);

49  

50   let response = await fetch(url, {

51   method: 'POST',

52   headers: {

53   'Content-Type': 'application/x-www-form-urlencoded',

54   }

55   })

56  

57   let data = await response.json();

58  

59   return data;

60   }

61  

62   //This funchtion will be to get userinfo by using acces_token and id_token

63   const getGoogleUserInfo = async (access_token, id_token) => {

64  

65   const url = new URL('https://www.googleapis.com/oauth2/v1/userinfo');

66  

67   const options = {

68   alt: 'json',

69   access_token

70   }

71  

72   url.search = new URLSearchParams(options);

73  

74   let response = await fetch(url, {

75   headers: {

76   Authorization: `Bearer ${id_token}`,

77   },

78   })

79  

80   let data = await response.json();

81   return data;

82   }

83  

84   const onSuccessGoogleOAuth = async (req, res) => {

85  

86   const { code } = req.query;

87  

88   try {

89   let { access_token, id_token } = await getGoogleAccessTokens(code);

90  

91   let data = await getGoogleUserInfo(access_token, id_token);

92  

93   let sessionToken = jwt.sign(data, process.env.JWT_SECRET_KEY);

94  

95   const date = new Date();

96   date.setDate(date.getDate() + 30);

97  

98   res.cookie('session', sessionToken, {

99   path: '/',

100   expires: date,

101   domain: process.env.COOKIE_DOMAIN,

102   })

103  

104   return res.redirect(process.env.FRONTEND_URL);

105  

106   } catch (error) {

107   return res.redirect(`${process.env.FRONTEND_URL}?error=Something wen wrong`);

108   }

109   }

110  

111   const verifyToken = (req, res) => {

112  

113   const { token } = req.params;

114  

115   try {

116   let validation = jwt.verify(token, process.env.JWT_SECRET_KEY);

117   return res.send({ validation });

118   } catch (error) {

119   return res.status(404).send({ validation: null });

120   }

121   }

122  

123   const signout = (req, res) => {

124   res.clearCookie('session', { domain: process.env.COOKIE_DOMAIN });

125   return res.redirect(process.env.FRONTEND_URL);

126   }

127  

128   export { handleGoogleConsentScreen, onSuccessGoogleOAuth, verifyToken, signout }

Now our nodejs endpoints are ready. lets connect it to our frontend and i will be using nextjs, a react framework

Connect with Frontend

  1. Initialize a next app with npx create-next-app
  2. Now lets create a simple button to signin with google

1   // app/page.js

2  

3   import Link from 'next/link'

4   import styles from './page.module.css'

5   import { cookies } from 'next/headers';

6  

7  

8   const getSession = async () => {

9   let token = cookies().get('session')?.value;

10  

11   let response = await fetch(`http://localhost:8080/api/oauth/verify/${token}`);

12   let { validation } = await response.json();

13  

14   return validation;

15   }

16  

17   export default async function Home() {

18  

19   let user = await getSession();

20  

21   return (

22   <main className={styles.main}>

23  

24   {user ? (

25   <div>

26   <img src={user.picture} alt={user.name} />

27   <h2> {user.name} </h2>

28   <p> {user.email} </p>

29   <Link href={'http://localhost:8080/api/oauth/signout'}>

30   <button> Signout </button>

31   </Link>

32   </div>

33   ) : (

34   <Link href={'http://localhost:8080/api/oauth/google'}>

35   <button> Signin with Google </button>

36   </Link>

37   )}

38  

39   </main>

40   )

41   }

Let's Break down what actually happens?

Source Code 😉

Check here 

Thank you😊 for joining me with the journey of Google OAuth integration with React and Node js. Hope this blog helps you a lot.

* * *