01. Introduction
Welcome to the world of the MERN stack! This guide will cover the basics of MongoDB, Express.js, React.js, and Node.js, along with interview tips. Whether a novice or an expert, you’ll gain the knowledge to build robust web applications. Let’s dive in and explore the power of the MERN stack.
1.1 Understanding the MERN Stack
The MERN stack combines MongoDB, Express.js, React.js, and Node.js to create modern web applications. This full-stack JavaScript approach ensures a seamless development process.
Picture 01: MERN stack Architecture
- MongoDB: A flexible, scalable NoSQL database that uses a document-based model, allowing for faster development and easy schema updates.
- Express.js: A minimalist web application framework for Node.js, offering routing, middleware, and template engines to simplify HTTP request handling and API building.
- React.js: A popular library for building user interfaces with a component-based architecture, providing efficient rendering and user interaction management.
- Node.js: A server-side JavaScript runtime that enables scalable, high-performance web applications with an event-driven, non-blocking I/O model.
The integration of these components allows for efficient development and code reuse. This guide will delve into each component’s features, best practices, and advanced concepts, equipping you to build powerful web applications with the MERN stack.
Let's start with the project.
02. Implementing Google OAuth
In my previous article, I explained step by step how to implement Google OAuth. You can refer to my previous article, "Understanding Google OAuth (Open Authorization)," for more details.
Here is a brief overview of the steps.
- Google API Console.
- Create a new project.
- APIs and Services.
- Create OAuth 2.0 Credentials.
- Configure the OAuth consent screen.
- Configure the OAuth client ID.
- Download the credentials.
I covered this topic in my previous article. Please read that article before continuing with this one. Now, let's continue with this article.
Picture 02: Web Server Applications
The authorization process starts when your application redirects a browser to a specified Google URL. This URL contains query parameters that define the type of access being requested. Google manages user authentication, session selection, and user consent. Upon completion, an authorization code is provided, which the application can exchange for an access token and a refresh token
Go to this link: https://console.cloud.google.com/cloud-resource-manager
2.1 Get the Google API key and Credentials
Step 01
Picture 03: Cloud resource manager
Go to the Navigation Menu and click it. Open the side panel and Go to the APIs and services Click it and go to click Credentials.
Step 02
Picture 04: The Path in Credentials
Step 03. Now you can see my exciting project “Student Management System”.
Picture 05: Download The path in Credentials
Click on the Download icon and get your OAuth client ID credentials in a JSON file. Go to the API Key Click on the SHOW KEY button. And copy the API KEY.
Picture 06: Open the API KEY popup window and copy the API KEY.
Successfully we get the API key and Credentials.
03. Apply the MERN stack
Above I shortly explain what the MERN stack is. Now I will apply Google OAuth how to work in the MERN stack. You can see this diagram.
Picture 07: See the integration of Google OAuth2 API, Node.js, Express, Passport, MongoDB, and other packages
To implement Google OAuth in a MERN stack application, first, integrate Google OAuth in the React front end using @react-oauth/google to handle the authentication flow. Wrap your application with GoogleOAuthProvider and use the GoogleLogin component to prompt users to sign in. On successful login, retrieve the user token and send it to the Node.js backend via an API request. In the Node.js server, verify the token using the Google API and extract the user information. Then, check if the user exists in the MongoDB database; if not, create a new user record. Finally, generate a session token for the authenticated user and manage it on the client side for subsequent requests.
I will explain our project structure.
- REACT
- NODE and EXPRESS
- MONGODB
04. React application
04.1 Create the New React application.
Now I’m going to create a new React project.
Step 01. Go to the Command Prompt “ CMD Open the CMD and follow this command.
npx create-react-app google-oauth-mern/gui
Step 02. Move to the client folder cd google-oauth-mern and cd gui folder.
Picture 08: Move to the GUI folder.
Open the terminal and type the ‘npm start’ command. Press the enter key.
Picture 09: See the view
We successfully installed React JS and ran it. We are now implementing Google Auth in React.js by installing the necessary packages.
04.2 Install the Required Packages
To implement Google Auth in React.js, we need to install the following packages.
- @react-oauth/google: Google OAuth2 using the new Google Identity Services SDK
- Axios: Promise-based HTTP client for the browser and node.js
- Jwt-decode: JSON Web Token can be decoded.
npm install @react-oauth/google axios jwt-decode
Picture 10: We installed the necessary packages
Picture 11: We check package.json package is installed or not
04.3 Create the login logout pages
Now have to create a folder as a Google-OAuth, inside of the folder create login and logout pages.
Picture 12: We create Login and Logout pages
Login page
import React from "react";
export default function Login() {
return (
<div>
<button type="button">Login</button>
</div>
);
}
I'm going to integrate the login.jsx and logout.jsx pages into the app.js file.
04.4 Integrate the login.jsx and logout.jsx pages
import "./App.css";
import Login from "./google-Oauth/Login";
import Logout from "./google-Oauth/Logout";
function App() {
return (
<div className="App">
<h1>Implementing Google OAuth in MERN</h1>
<div className="center">
<Login />
</div>
<div className="center">
<Logout />
</div>
</div>
);
}
export default App;
Picture 13: Go to run the app. And see the view in the browser
Now we want to create the env file for sensitive information
04.5 Create the env file
The .env file in a React and Node.js application is used to store environment variables, which are configuration settings that your application needs to run. These variables can include sensitive information like API keys, database connection strings, or any other configuration parameters specific to the environment where the application is running.
Let's create an env file.
- Go to the dotenv npm page. Install the npm package for dotenv for your node js application.
- Create an env file in reactjs/ node-js. Do not create a js file. Name it .env.
Go to the Client project, create the ‘.env’ file and add Client-Id and API-key
The process for obtaining the OAuth client ID and API key is already explained in pictures 5 and 6.
Picture 14: Add the client ID and API key
04.6 Create the Google Login
We can create the Google login by referring to this page: React OAuth2 | Google. We have already installed @react-oauth/google.
import React from "react";
import {GoogleOAuthProvider,GoogleLogin,googleLogout} from "@react-oauth/google";
import { jwtDecode } from "jwt-decode";
const CLIENT_ID = process.env.REACT_APP_GOOGLE_CLIENT_ID;
export default function login() {
const handelLogin = (googleData) => {
const userData = jwtDecode(googleData);
console.log("userData====>",userData);
};
return (
<div className="App">
<button type="button">
<GoogleOAuthProvider clientId={CLIENT_ID}>
<GoogleLogin
onSuccess={(credentialResponse) => {
handelLogin(credentialResponse.credential);
}}
onError={() => {}}
/>
</GoogleOAuthProvider>
</button>
</div>
);
}
Now I'm going to explain the code step by step.
<GoogleOAuthProvider clientId={Your_CLIENT_ID}>
<GoogleLogin
onSuccess={(credentialResponse) => {
handelLogin(credentialResponse.credential);
}}
onError={() => {}}
/>
</GoogleOAuthProvider>
- GoogleOAuthProvider: This is a component from the @react-oauth/google library that wraps around your application or a part of your application where you want to enable Google OAuth2 authentication.
<GoogleOAuthProvider clientId={CLIENT_ID} />
- This component wraps the Google login functionality and takes a clientId prop, which is your Google OAuth client ID.
<GoogleLogin />
- GoogleLogin: This component renders a Google login button
- onSuccess: This prop specifies a callback function that gets called when the login is successful. It receives a credentialResponse object, from which you can extract the user's credential and pass it to the handle login function.
const handelLogin = (googleData) => {
const userData = jwtDecode(googleData);
console.log(userData);
};
- handleLogin: This is a function that handles the Google login data.
- googleData: This parameter represents the credential data received from Google after a successful login.
- jwtDecode: This function (usually from a library like jwt-decode) decodes the JSON Web Token (JWT) contained in googleData.
- userData: This variable holds the decoded user information extracted from the JWT.
- console.log(userData): This line logs the decoded user information to the console.
Now, we can run the application.
Picture 15: See the view Google login button and logout button available
Click on the “Sign in with Google” Button.
Picture 16: See the view Google login available
Picture 17: Login with a Gmail account
Get the console output of userData here.
Picture 18: Now you can see the login information here
Successfully we get the Goole OAuth token. retrieve the user token and send it to the Node.js backend via an API request.
04.6.1 Initialization of State
const [loginData, setLoginData] = useState(
localStorage.getItem("loginData")
? JSON.parse(localStorage.getItem("loginData"))
: null
);
Your state is initialized correctly, checking if loginData exists in local storage. If it does, it parses and uses it; otherwise, it sets the state to null.
04.6.2 Define the handleLogin Function
const handelLogin = async (googleData) => {
//const userData = jwtDecode(googleData);
try {
const res = await fetch("http://localhost:5000/api/google-login", {
method: "POST",
body: JSON.stringify({token: googleData, }),
headers: { "Content-Type": "application/json" },
});
if (!res.ok) {
throw new Error("Failed to log in with Google");
}
const data = await res.json();
setLoginData(data);
localStorage.setItem("loginData", JSON.stringify(data));
} catch (error) {
console.error("Error logging in:", error);
}
};
- The function handleLogin takes googleData as an argument, which contains the Google authentication data.
- It makes a POST request to the server with the googleData token.
- If the response is not OK, it throws an error.
- If the response is successful, it parses the JSON response, updates the state with the received data, and stores this data in localStorage.
- If an error occurs at any point, it logs the error to the console.
Login.jsx Pages code
import React from "react";
import {
GoogleOAuthProvider,
GoogleLogin,
googleLogout,
} from "@react-oauth/google";
import { jwtDecode } from "jwt-decode";
const CLIENT_ID = process.env.REACT_APP_GOOGLE_CLIENT_ID;
export default function login() {
const [loginData, setLoginData] = useState(
localStorage.getItem("loginData")
? JSON.parse(localStorage.getItem("loginData"))
: null
);
const handelLogin = async (googleData) => {
//const userData = jwtDecode(googleData);
try {
const res = await fetch("http://localhost:5000/api/google-login", {
method: "POST",
body: JSON.stringify({token: googleData, }),
headers: { "Content-Type": "application/json" },
});
if (!res.ok) {
throw new Error("Failed to log in with Google");
}
const data = await res.json();
setLoginData(data);
localStorage.setItem("loginData", JSON.stringify(data));
} catch (error) {
console.error("Error logging in:", error);
}
};
return (
<div className="App">
<button type="button">
<GoogleOAuthProvider clientId={CLIENT_ID}>
<GoogleLogin
onSuccess={(credentialResponse) => {
handelLogin(credentialResponse.credential);
}}
onError={() => {}}
/>
</GoogleOAuthProvider>
</button>
</div>
);
}
We will create the Node.js backend.
05. Node.js backend application
In my previous article, I provided a step-by-step guide on Setting up the Node.js Environment and Running a Simple Node Server Project. If you're new to Node.js, I recommend reading that article first for detailed instructions. Once you're familiar with the setup, return to this article for further insights.
05.1. Create the Node.js application.
Now I’m going to create a new folder as an API and inside of the folder open the terminal and type npm init -y.
To install an npm package, go to the terminal and type npm init -y. This command initializes a new npm project with default settings, skipping the prompts that npm init would normally display. During the standard npm init process, you'll be asked several questions, including the package name. You can specify your own package name, or it will default to the name of the project folder. By using the -y flag, npm init -y automatically sets the package name to the default project folder name without prompting you for input.
Picture 19: Now you can see the \package.json info here
05.1. Install NPM Packages
Install the necessary npm packages: Express, nodemon, body-parser, and Mongoose. These packages are essential for working with API projects. Here are the details of each package.
- Express: A web application framework for Node.js that simplifies building and managing web applications.
- Body-parser: A middleware for Node.js that parses incoming request bodies in a middleware before your handlers, making it easier to handle form submissions and JSON payloads.
- Nodemon: A utility that automatically restarts your Node.js application when file changes in the directory are detected, streamlining development and testing.
- Mongoose: An object data modeling (ODM) library for MongoDB and Node.js, providing a straightforward, schema-based solution to model your application data.
To install these packages, run the following command in your project directory.
npm install express nodemon body-parser mongoose
Picture 20: You can see the dependencies here. I installed express, body-parser, nodemon, and Mongoose npm packages
05.2. Create index.js
Create an Index page index.js.
const express = require("express");
const app = express();
app.get("/", function (req, res) {
res.send("Hello C# Corner.");
});
app.listen(3000);
1. Import the Express module
const express = require("express");
This line imports the Express module, which is a web framework for Node.js. express will be used to create an Express application.
2. Create an Express application
const app = express();
This line creates an instance of an Express application.
3. Define a route for GET requests to the root URL ("/")
app.get("/", function (req, res) {
res.send("Hello C# Corner.");
});
It has a callback function (req, res) req = it listens to the incoming request object, and res = responds accordingly using the response object.
4. Start the server and listen on port 3000
app.listen(3000);
It listens for incoming requests on port 3000. Once the server is running, it will be accessible via http://localhost:3000.
5. Config Script package.json
Add the line start script from package.json.
"scripts": {
"start": "nodemon index.js"
}
run the node js “npm start”.
Picture 21: You can see that this runs the node js “npm start”. App listen 5000, script running nodemon index.js
Verify the response body using Postman at localhost port 5000.
Picture 22: You can see this GET method call, which returns the message 'Hello C# Corner.' with a status of success (200 OK)
06. Get the MongoDB Connection String
Creating a MongoDB Atlas Account and Establishing a MongoDB Connection.
If you're looking to create a MongoDB Atlas account and set up a MongoDB connection, I've got you covered. I’ve detailed these processes in my previous articles, which you can find linked below.
How to Create a MongoDB Atlas Account?
For a step-by-step guide on creating a MongoDB Atlas account, check out my article: How to Create a MongoDB Atlas Account.
Node.js RESTful API Project with Express, MongoDB, and Postman.
To learn how to build a Node.js RESTful API project using Express, MongoDB, and Postman, refer to my detailed guide here: Node.js RESTful API Project with Express, MongoDB, and Postman.
Here is the link. Please read it; I will continue with this article.
Go to the MongoDB cluster on the dashboard.
Picture 23: Click on the "Connect" button in the cluster on the dashboard
DB Connection
Picture 24: Click on the "Drivers" tab in the dashboard
- Open the MongoDB Driver.
- Select your driver and version.
- Copy your connection string to your application code.
Picture 25. 01: You will select your driver with the version. 02. You can copy the Connection string
07. Connect the API with MongoDB
07.1. Create the API env file
Now I'm going to create the env file. In this article, I explain the process under the heading '04.5 Create the env file'. Follow these steps:"
MONGO_DB=mongodb+srv://<Username>:<Password>@<clusterName>.joofg8v.mongodb.net/<your_database_name>?retryWrites=true&w=majority
Now I'm going to create the DB as a “GoogleOAuth”. Env file mongoDB variable set DB name.
MONGO_DB=mongodb+srv://<Username>:<Password>@<clusterName>.joofg8v.mongodb.net/GoogleOAuth?retryWrites=true&w=majority
Picture 26: You can see the env setup MONGO_DB and PORT
You can pass your MongoDB connection string in MONGO_DB in env.
07.2. DB Connection Check
Check whether the DB connection is successful or not.
require("dotenv").config();
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const MONGO_DB = process.env.MONGO_DB;
const PORT = process.env.PORT;
app.get("/", function (req, res) {
res.send("Hello C# Corner.");
});
mongoose
.connect(MONGO_DB)
.then(() => {
console.log("connected to MongoDB");
app.listen(PORT, () => {
console.log(`Node API app is running on port ${PORT}`);
});
})
.catch((error) => {
console.log(error);
});
const mongoose = require("mongoose");
This line imports the Mongoose library, which is an Object Data Modeling (ODM) library for MongoDB and Node.js.
Load Environment Variables
const MONGO_DB = process.env.MONGO_DB;
const PORT = process.env.PORT;
These lines load the MongoDB connection string (MONGO_DB) and the port number (PORT) from environment variables.
Connect to MongoDB
mongoose
.connect(MONGO_DB)
.then(() => {
console.log("connected to MongoDB");
app.listen(PORT, () => {
console.log(`Node API app is running on port ${PORT}`);
});
})
.catch((error) => {
console.log(error);
});
mongoose.connect(MONGO_DB): This attempts to connect to the MongoDB database using the connection string stored in the MONGO_DB environment variable. It returns a promise. If the connection is successful, the callback function inside then is executed.
.catch((error) => { ... }): If the connection fails, the callback function inside catch is executed.
Picture 27: Successfully connected to the database
07.3. Verify the token using the Google API
- Verify the token using the Google API.
- Extract the user information.
- Check if the user exists in the MongoDB database; if not, create a new user record.
- Generate a session token for the authenticated user.
Picture 28: Verify the token and Check if the user exists in the MongoDB database; if not, create a new user record
07.4. Create a Model for Data in the Database
- Create a new folder as models.
- Create a userModel.js page. And Continue this code.
Picture 29: You can see this usermodel
Here I can share userModel.js.
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
googleId: { type: String, required: true, unique: true },
email: { type: String, required: true },
name: { type: String, required: true },
picture: { type: String }
});
module.exports = mongoose.model('User', userSchema);
This defines the structure of a user document with four fields.
- googleId: A unique identifier from Google (string, required, unique).
- email: The user's email (string, required).
- name: The user's name (string, required).
- picture: The URL of the user's profile picture (string).
07.5. Add the client ID and Google API key in env
The process for obtaining the OAuth client ID and API key is already explained in pictures 5 and 6.
I explain the process under the heading '07.1 Create the API env file'. Follow these steps."
- REACT_APP_GOOGLE_CLIENT_ID =
- REACT_APP_GOOGLE_API_KEY=
07.6. Install NPM Packages
- ( Google Auth Library: Node.js, jsonwebtoken, and Cors)
- Installing Google Auth Library: Node.js Client This is the officially supported Node.js client library by Google for using OAuth 2.0 authorization and authentication with Google APIs.
npm i google-auth-library
- Jsonwebtoken is a library in Node.js used to create, sign, and verify JSON Web Tokens (JWTs). JWTs are a compact, URL-safe means of representing claims between two parties. They are often used for authentication and secure information exchange.
npm i jsonwebtoken
- CORS is a node.js package for providing a Connect/Express middleware that can be used to enable CORS with various options.
npm i cors
07.7. Create a Google Login Endpoint
const CLIENT_ID = process.env.GOOGLE_CLIENT_ID;
const JWT_SECRET = process.env.JWT_SECRET;
const client = new OAuth2Client(CLIENT_ID);
app.use(express.json());
app.use(cors({ origin: "http://localhost:3000" }));
app.post("/api/google-login", async (req, res) => {
const { token } = req.body;
try {
// Verify the token using Google API
const ticket = await client.verifyIdToken({
idToken: token,
audience: CLIENT_ID,
});
const payload = ticket.getPayload();
const { sub, email, name, picture } = payload;
// Check if the user exists in the MongoDB database
let user = await User.findOne({ googleId: sub });
if (!user) {
// Create a new user record if not exist
user = new User({
googleId: sub,
email,
name,
picture
});
await user.save();
}
// Generate a session token for the authenticated user
const sessionToken = jwt.sign({ userId: user._id }, JWT_SECRET, { expiresIn: '1h' });
// Send the session token to the client
res.json({ success: true, sessionToken });
} catch (error) {
console.error('Error verifying token:', error);
res.status(401).json({ success: false, message: 'Invalid token' });
}
});
01. Initialize OAuth2 Client
const client = new OAuth2Client(CLIENT_ID);
Prepares the Google OAuth2 client for token verification.
02. Middleware Setup
app.use(express.json());
app.use(cors({ origin: "http://localhost:3000" }));
Configures Express to parse JSON and handle CORS for requests from.
Google Login Endpoint
app.post("/api/google-login", async (req, res) => {
const { token } = req.body;
try {
// 01. Verify the token using Google API
const ticket = await client.verifyIdToken({
idToken: token,
audience: CLIENT_ID,
});
const payload = ticket.getPayload();
const { sub, email, name, picture } = payload;
// 02. Check if the user exists in the MongoDB database
let user = await User.findOne({ googleId: sub });
if (!user) {
// 03. Create a new user record if not exist
user = new User({
googleId: sub,
email,
name,
picture
});
await user.save();
}
// 04. Generate a session token for the authenticated user
const sessionToken = jwt.sign({ userId: user._id }, JWT_SECRET, { expiresIn: '1h' });
// 05. Send the session token to the client
res.json({ success: true, sessionToken });
} catch (error) {
console.error('Error verifying token:', error);
res.status(401).json({ success: false, message: 'Invalid token' });
}
});
Google Login Endpoint: Handles the /API/google-login route to.
- Verify the Google token.
- Extract user information.
- Check or create a user in MongoDB.
- Generate a session token.
- Send the session token back to the client.
08. Run the Application
Go to the GUI folder, open the terminal in your VS Code, and run this command: npm start. The same command applies to the API folder as well.
Picture 30: Run this command GUI and API: npm start
Picture 31: Click on the “Sign in with Google” Button
Picture 32: Login in your email
Picture 33: See the network tab API call “google-login”. Status 200
Successfully Make the API Call
- Implement the API call as described in the code.
- In your browser, open the Developer Tools (usually by pressing F12 or right-clicking and selecting "Inspect").
- Go to the "Network" tab.
- Trigger the Google login process in your application.
- Look for the network request named "google-login" in the Network tab.
- Ensure that the status of this request is 200, indicating a successful API call.
09. View the Database
Go to the MongoDB cluster on the dashboard.
- Click on the Database Button and
- Click on your cluster.
Picture 34: Click on the cluster
After you get the cluster dashboard, Click on the Collections tab.
Picture 35: Click on the Collections tab
Picture 36: See the DB dashboard registered user details here
10. View the Login Data in the GUI
Successfully made the API call as explained in Picture 33. Check the network tab for the API call 'google-login' with status 200. And we get the response from API " loginData.sessionToken". we modify the code by the session token.
10.1 Update user state
const [user, setUser] = useState({});
useEffect(() => {
if (loginData) {
const decodedUser = jwtDecode(loginData.sessionToken);
setUser(decodedUser);
}
}, [loginData]);
const [user, setUser] = useState({});
Initializes a state variable user with an empty object {} using useState.
useEffect(() => {
// Your code here
}, [loginData]);
Runs the code inside the useEffect callback function when login data changes.
Inside the useEffect callback
- Check if loginData is true.
- Decodes the sessionToken from loginData using jwtDecode.
- Updates the user state with the decoded user object (decodedUser).
<div className="App">
{loginData ? (
<>
<div>
<img src={user.picture} alt={user.userName} />
<h3>{user.email}</h3>
<h6>{user.userName}</h6>
</div>
<div>
<button onClick={handelLogout}>Logout</button>
</div>
</>
) : (
<div className="App">
<button type="button">
<GoogleOAuthProvider clientId={CLIENT_ID}>
<GoogleLogin
onSuccess={(credentialResponse) => {
handelLogin(credentialResponse.credential);
}}
onError={() => {}}
/>
</GoogleOAuthProvider>
</button>
</div>
)}
</div>
The code conditionally renders different content based on the presence of loginData. If loginData is present, it shows the user's profile picture, email, and username, along with a logout button that triggers the handelLogout function. If loginData is not present, it shows a Google login button using the GoogleOAuthProvider and GoogleLogin components. The GoogleLogin component handles the login process, triggering the handelLogin function on success, while the onError prop is left empty.
Picture 37: Successfully log in and view the user details
10.2 HandeLogout function
const handelLogout = () => {
setLoginData(null);
localStorage.removeItem("loginData");
googleLogout();
};
setLoginData(null);
Sets the state variable loginData to null. This likely indicates that the user is no longer logged in, as null typically represents the absence of a logged-in state.
localStorage.removeItem("loginData");
Removes the item with the key "loginData" from the browser's localStorage. This is likely used to clear any persisted login data stored locally, ensuring the user isn't automatically logged back in on subsequent visits.
googleLogout();
It calls a function googleLogout() that presumably handles logging users out of a Google-related service or OAuth session.
Picture 38: Successfully Logout
Full Code of login.jsx
import React, { useEffect, useState } from "react";
import {
GoogleOAuthProvider,
GoogleLogin,
googleLogout,
} from "@react-oauth/google";
import { jwtDecode } from "jwt-decode";
const CLIENT_ID = process.env.REACT_APP_GOOGLE_CLIENT_ID;
export default function Login() {
const [loginData, setLoginData] = useState(
localStorage.getItem("loginData")
? JSON.parse(localStorage.getItem("loginData"))
: null
);
const [user, setUser] = useState({});
useEffect(() => {
if (loginData) {
const decodedUser = jwtDecode(loginData.sessionToken);
setUser(decodedUser);
}
}, [loginData]);
const handelLogin = async (googleData) => {
try {
const res = await fetch("http://localhost:5000/api/google-login", {
method: "POST",
body: JSON.stringify({ token: googleData }),
headers: { "Content-Type": "application/json" },
});
if (!res.ok) {
throw new Error("Failed to log in with Google");
}
const data = await res.json();
setLoginData(data);
localStorage.setItem("loginData", JSON.stringify(data));
} catch (error) {
console.error("Error logging in:", error);
}
};
const handelLogout = () => {
setLoginData(null);
localStorage.removeItem("loginData");
googleLogout();
};
return (
<div className="App">
{loginData ? (
<>
<div>
<img src={user.picture} alt={user.userName} />
<h3>{user.email}</h3>
<h6>{user.userName}</h6>
</div>
<div>
{" "}
<button onClick={handelLogout}>Logout</button>
</div>
</>
) : (
<div className="App">
<button type="button">
<GoogleOAuthProvider clientId={CLIENT_ID}>
<GoogleLogin
onSuccess={(credentialResponse) => {
handelLogin(credentialResponse.credential);
}}
onError={() => {}}
/>
</GoogleOAuthProvider>
</button>
</div>
)}
</div>
);
}
Summary
The article explores integrating Google OAuth into a MERN (MongoDB, Express.js, React.js, Node.js) stack application. It begins with an introduction to the MERN stack's components and benefits. The implementation of Google OAuth involves several key steps.
- Setting up Google OAuth credentials through the Google API Console.
- Integrating Google OAuth in a React frontend using @react-oauth/google for authentication.
- Handling user authentication and token exchange between the frontend and backend (Node.js).
- Verifying tokens using Google APIs and storing user information in MongoDB.
- Running and testing the integrated application, including setting up necessary environment variables and configuring API endpoints.
Throughout the article, detailed steps are provided for setting up both the frontend and backend components, ensuring a comprehensive guide to implementing Google OAuth in a MERN stack application.
I'm attaching the GitHub project link here. https://github.com/navamayoo/google-oauth-mern