0% found this document useful (0 votes)
59 views44 pages

How To Secure Your MERN Stack App With JWT-Based User Authentication and Authorization

Uploaded by

mohdaffan1254
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
59 views44 pages

How To Secure Your MERN Stack App With JWT-Based User Authentication and Authorization

Uploaded by

mohdaffan1254
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 44

07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

Forum Donate

Support our charity and our mission. Donate to freeCodeCamp.org.

MAY 15, 2023 / #AUTHENTICATION

How to Secure Your MERN


Stack App with JWT-Based
User Authentication and
Authorization
FADAHUNSI SEYI SAMUEL

MongoDB, Express, React, and Node.js are the


components of the MERN stack, one of the most widely
used web development stacks out there today.

The MERN stack enables programmers to create dependable web


applications with strong capabilities. Yet, security should be a key
https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 1/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

concern with any web application. Forum Donate

Support our charity and our mission. Donate to freeCodeCamp.org.


User authentication and permissions are some of the most important
security features of any web service. In order to protect sensitive
information and stop unauthorized access to important functions,
these make sure that only authorized users can access certain areas of
the application.

By the end of this article, you will have a firm grasp on how to
integrate JWT (Json Web Token)-based user authentication and
authorization into your MERN stack web application.

Here's what we'll cover:


What is User Authentication & Authorization?

What is the MERN Stack?

Why Use the MERN Stack?

How to Set Up the Project Environment

How to Create a New React Application

Node.js and Express.js Installation and Configuration

How to Set Up MongoDB

How to Implement the Backend

How to Handle the SIGNUP Route

How to Handle the LOGIN Route

How to Handle the HOME Route

How to Implement the Frontend

How to Handle the Signup Logic

How to Handle the Login Logic

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 2/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

How to Handle the Home Page Logic Forum Donate

Conclusion
Support our charity and our mission. Donate to freeCodeCamp.org.

What is User Authentication &


Authorization?
In application security, authentication and authorization are two
crucial ideas that work together to guarantee access to the resources
of an application.

Many people frequently confuse these words – but after reading this
guide, will we? NOT AGAIN!

Authentication
Verifying a user's or an entity's identity is the process called
Authentication. It entails validating the user's credentials, such as a
username and password, to ensure that the user is who they claim to
be.

Authorization
The process of authorizing or refusing access to particular resources
or functions within an application is known as Authorization. Once a
user has been verified as authentic, the program checks their level of
authorization to decide which areas of the application they can access.

Authentication is comparable to when a college applicant is admitted


to a program based on the results of a written exam. The student is
permitted on school grounds, but is not permitted in a department or
class that is not their own (that was not given to them during
admission). This action is known as Authorization.
https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 3/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

Forum Donate

What is the MERN Stack?


Support our charity and our mission. Donate to freeCodeCamp.org.

Let's talk about the various elements of the MERN stack before we
start creating the authentication mechanism.

1. MongoDB is a NoSQL database that uses dynamic schemas


and documents that resemble JSON to store data. MongoDB is
a popular option for creating scalable web applications
because it is effective at managing big amounts of data.

2. Express.js is a Node.js web application framework that offers a


selection of functionality for creating online applications.
Express.js is a well-liked option for developing online
applications since it is compact, quick, and simple to use.

3. React.js is a JavaScript library used to create user interfaces.


By disassembling complicated user interfaces into smaller,
reusable components, React.js offers a declarative method for
doing so.

4. Node.js is based on the V8 JavaScript engine in Chrome, and is


a JavaScript runtime. The ability to run JavaScript on the
server-side makes Node.js the perfect platform for creating
web applications.

Why Use the MERN Stack?


The MERN stack is a great option for developing web applications
since it includes all of the technologies needed to create a cutting-
edge, scalable online application.

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 4/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

Following a discussion of the various elements of the MERN stack, weDonate


Forum
will use code snippets to develop a whole user authentication system
Support our charity and our mission. Donate to freeCodeCamp.org.
from scratch.

How to Set Up the Project


Environment
To get started with building the authentication system, we first need
to set up the project. We will create a new React application using
create-react-app and install the required dependencies. We will also
set up MongoDB and configure our Node.js server.

NB: In this article, we will be making use of Visual studio code editor,
which I highly recommend.

Before we dive into this, you're going to create a folder which will
contain other sub folders as you move on in this article.

After creating your folder, it should look like the image below:

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 5/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

Forum Donate

The folder
Supportyou
ourjust created
charity willmission.
and our containDonate
two sub folders called the
to freeCodeCamp.org.
client and server . Run the commands below in your terminal to
create the sub folders:

mkdir client

This will create the client sub folder.

mkdir server

This will create the server sub folder. Your application folder should
look like this:

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 6/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

How to Create a New React Application


Forum Donate

You can create


Support ouracharity
new React application
and our using to
mission. Donate create-react-app .
freeCodeCamp.org.
Open your terminal and run the below command to create a new
React application.

But first, you will need to go into the client folder using cd client ,
then run the following command:

npx create-react-app

After the command above has successfully created the app, type npm
start in your terminal. Make sure you're in your client directory.
Your output should look like the image below:

Before we move to the server directory, you will need to remove some
boilerplate in your React application. Your client should look like the
https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 7/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

image below; Forum Donate

Support our charity and our mission. Donate to freeCodeCamp.org.

Once you're done with the above, restart your React application by
running npm start in your terminal. Your application should be
looking like this:

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 8/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

Forum Donate
Now, you've successfully setup your client side of the application 😊
Support our charity and our mission. Donate to freeCodeCamp.org.
yeah!

Node.js and Express.js Installation and


Configuration
To setup your backend application, run mkdir server in your terminal
to get into the server sub folder. After getting into the server sub
folder, run the following command to initialize the backend
application:

npm init --yes

The npm init --yes command in Node.js creates a new


package.json file for a project with default settings, without asking
the user any questions.

The --yes or -y flag tells npm to use default values for all prompts
that would normally appear during the initialization process.

The server folder should now contain a package.json file just like so:

{
"name": "server",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 9/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

"author": "",
Forum Donate
"license": "ISC"
}
Support our charity and our mission. Donate to freeCodeCamp.org.

To install Express.js and other dependencies, run the following


commands in your terminal:

npm install express cors bcrypt cookie-parser nodemon jsonwebtoken mongo

The above commands install the following dependencies:

Express.js , which is our Node.js web application framework.

bcrypt , which helps us hash the user's password.

cookie-parser is the the cookie-parser middleware that


handles cookie-based sessions. It extracts information from
cookies that may be required for authentication or other
purposes.

nodemon is a tool used to automatically restart a Node.js


application whenever changes are made to the code.

CORS is a middleware used to enable Cross-Origin Resource


Sharing (CORS) for an Express.js application.

jsonwebtoken helps us create and verify JSON Web Tokens.

dotenv allows you to store configuration data in a .env file,


which is typically not committed to version control, to separate
sensitive information from your codebase. This file contains
key-value pairs that represent the environment variables.
https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 10/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

Forum Donate
After installing the required dependencies, create a new file called
Support our charity and our mission. Donate to freeCodeCamp.org.
index.js in the root directory of your server sub folder of your
application. The index.js file will contain our Node.js server.

In the index.js file of your server , add the following code:

const express = require("express");

const app = express();


const PORT = 4000;

app.listen(PORT, () => {
console.log(`Server is listening on port ${PORT}`);
});

Before you start the server, update your package.json file in the
server by adding the code below:

"scripts":{
start: "nodemon index.js",
test: 'echo "Error: no test specified" && exit 1',
};

This will make sure your application restarts on any update. Now, you
can start your server by running npm start in your terminal.

If all these are successfully executed, your terminal should look like
this:

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 11/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

Forum Donate

Support our charity and our mission. Donate to freeCodeCamp.org.

How to Set Up MongoDB


You're almost done with setting up your application. If you do not have
mongodb installed your computer, follow these steps.

Now, I assume you have successfully installed mongodb on your


computer. To link your database to your backend, follow the
procedures below.

STEP 1: Go into your MongoDB cloud clusters, which should look like
the image below:

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 12/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

Forum Donate

Support our charity and our mission. Donate to freeCodeCamp.org.

STEP 2: Click on the Database Access, which is on the left of the


sidebar. Click on ADD NEW DATABASE USER which will pop up a modal,
like the image below:

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 13/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

STEP 3: Fill out the Password Authentication with yourForum


desired Donate
username and password for the database of this particular project.
Support our charity and our mission. Donate to freeCodeCamp.org.

STEP 4: Before saving this, click the Built-in Role dropdown, and
select Read and write to any database . Now, go ahead to click Add
user .

STEP 5: Click on Database , and on the left side of the sidebar, click the
connect button, which is beside View Monitoring . A modal popup
will be displayed, then click connect your application and copy the
code snippet you find there.

You will replace <username> and <password> with the username and
password you created in STEP 3 in your index.js file in the server
folder.

Before going into your index.js file, you will create a .env file in
your server directory, which will contain your MONGODB_URL , PORT ,
database_name , and database_password like the code below:
https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 14/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

Forum Donate

Support our charity and our mission. Donate to freeCodeCamp.org.


MONGO_URL =
"mongodb+srv://database_name:[email protected]
PORT = 4000;

Once you're done with this, go into your index.js in your server
directory, and update it with the code below:

const express = require("express");


const mongoose = require("mongoose");
const cors = require("cors");
const app = express();
require("dotenv").config();
const { MONGO_URL, PORT } = process.env;

mongoose
.connect(MONGO_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => console.log("MongoDB is connected successfully"))
.catch((err) => console.error(err));

app.listen(PORT, () => {
console.log(`Server is listening on port ${PORT}`);
});

app.use(
cors({
origin: ["http://localhost:4000"],
methods: ["GET", "POST", "PUT", "DELETE"],
credentials: true,
})
);

app.use(express.json());

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 15/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

Forum Donate
In the code above, we are configuring our application to be able to
haveSupport
access to
ourthe
charity file.
.envand ourYou can get
mission. the information
Donate in your .env
to freeCodeCamp.org.
file by doing process.env .

So you're destructing the values from the .env file by doing


process.env so you don't repeat yourself (DRY) which is a good
engineering practice.

CORS (Cross origin resource sharing): You can allow requests


from other domains to access the resources on your server by
using the cors() express middleware function. The CORS
headers that your server should include in the response can be
specified using the function's optional configuration object
parameter, which is taken as a parameter by the function which
is the origin , methods and credentials .

express.json(): The express.json() will add a body property


to the request or req object. This includes the request body's
parsed JSON data. req.body in your route handler function
will allow you to access this data.

useNewUrlParser: This property specifies that Mongoose


should use the new URL parser to parse MongoDB connection
strings. This is set to true by default.

useUnifiedTopology: This property specifies that Mongoose


should use the new Server Discovery and Monitoring engine.
This is set to false by default.

After following the steps above, you will restart your application by
doing npm start in your server directory. Your terminal should look
like the image below;

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 16/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

Forum Donate

Support our charity and our mission. Donate to freeCodeCamp.org.

How to Implement the Backend


Create the following folders in the server directory of your
application after first ensuring that you are in that directory.
Controllers , Middlewares , Routes , Models , and util are the
names of these folders.

How to Handle the SIGNUP Route


Create a file called UserModel.js in the Models directory and put the
following code into it to get started:

const mongoose = require("mongoose");


const bcrypt = require("bcryptjs");

const userSchema = new mongoose.Schema({


email: {
type: String,
required: [true, "Your email address is required"],
unique: true,
https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 17/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

},
Forum Donate
username: {
type: String,
Support our charity and our mission. Donate to freeCodeCamp.org.
required: [true, "Your username is required"],
},
password: {
type: String,
required: [true, "Your password is required"],
},
createdAt: {
type: Date,
default: new Date(),
},
});

userSchema.pre("save", async function () {


this.password = await bcrypt.hash(this.password, 12);
});

module.exports = mongoose.model("User", userSchema);

The user schema and user password will be created in the above code
using mongoose and bcryptjs , respectively, for security purposes.

The password is hashed for security reasons prior to saving the user.

Next, you will setup a function to handle the generation of a atoken,


which will be called SecretToken.js in the util folder. Copy and
paste the code below into the newly created file ( SecretToken.js ):

require("dotenv").config();
const jwt = require("jsonwebtoken");

module.exports.createSecretToken = (id) => {


return jwt.sign({ id }, process.env.TOKEN_KEY, {
expiresIn: 3 * 24 * 60 * 60,
});
};

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 18/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

Forum Donate
OnceSupport
that's done, create
our charity a file
and our called
mission.AuthController.js in the
Donate to freeCodeCamp.org.
Controllers directory and paste in the following code:

const User = require("../Models/UserModel");


const { createSecretToken } = require("../util/SecretToken");
const bcrypt = require("bcryptjs");

module.exports.Signup = async (req, res, next) => {


try {
const { email, password, username, createdAt } = req.body;
const existingUser = await User.findOne({ email });
if (existingUser) {
return res.json({ message: "User already exists" });
}
const user = await User.create({ email, password, username, createdAt
const token = createSecretToken(user._id);
res.cookie("token", token, {
withCredentials: true,
httpOnly: false,
});
res
.status(201)
.json({ message: "User signed in successfully", success: true, user
next();
} catch (error) {
console.error(error);
}
};

The user's inputs are obtained from the req.body in the code above,
and you then check the email to make sure no past registrations have
been made. We'll use the values obtained from req.body to create
the new user after that has occurred.

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 19/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

You don't need to worry about how the unique _id wasForum
obtained Donate
because MongoDB always assigns a new user with a unique _id
Support our charity and our mission. Donate to freeCodeCamp.org.

The newly formed user 's _id is then supplied as an parameter to the
createSecretToken() function, which handles token generation.

The cookie will be sent to the client with key of "token" , and value of
token .

Next, create a file called AuthRoute.js in the Routes directory. Paste


the code below into the newly created file:

const { Signup } = require("../Controllers/AuthController");


const router = require("express").Router();

router.post("/signup", Signup);

module.exports = router;

In the code above, the /signup route has a post method attached to
it, when it's been called, the Signup controller will be executed.

Next, update your index.js file so it can be aware of the routes. Your
index.js file should look like the code below:

const express = require("express");


const mongoose = require("mongoose");
const cors = require("cors");
const app = express();
require("dotenv").config();
const cookieParser = require("cookie-parser");
const authRoute = require("./Routes/AuthRoute");
const { MONGO_URL, PORT } = process.env;
https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 20/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

Forum Donate
mongoose
.connect(MONGO_URL, {
Support our charity and our mission. Donate to freeCodeCamp.org.
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => console.log("MongoDB is connected successfully"))
.catch((err) => console.error(err));

app.listen(PORT, () => {
console.log(`Server is listening on port ${PORT}`);
});

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

app.use(express.json());

app.use("/", authRoute);

The cookie-parser manages cookie-based sessions or extracts data


from cookies. It's added to the code above along with the authRoute
that the application will utilize.

Now, let's go ahead to test the /signup route with a tool called
Postman. Make sure you're in the server directory in the terminal,
then run npm start to start your application.

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 21/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

Forum Donate

Support our charity and our mission. Donate to freeCodeCamp.org.

The image above shows the response gotten when a request is sent.

The image above shows the generated cookie from the response.

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 22/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

Forum Donate

Support our charity and our mission. Donate to freeCodeCamp.org.

The image above illustrates what happens when you try to use a
registered email.

By now, the user will be created in the database like the image below:

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 23/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

How to Handle the LOGIN Route Forum Donate


Open the AuthController.js
Support file in the
our charity and our mission. Controllers
Donate directory, and
to freeCodeCamp.org.
update it with the code below:

module.exports.Login = async (req, res, next) => {


try {
const { email, password } = req.body;
if(!email || !password ){
return res.json({message:'All fields are required'})
}
const user = await User.findOne({ email });
if(!user){
return res.json({message:'Incorrect password or email' })
}
const auth = await bcrypt.compare(password,user.password)
if (!auth) {
return res.json({message:'Incorrect password or email' })
}
const token = createSecretToken(user._id);
res.cookie("token", token, {
withCredentials: true,
httpOnly: false,
});
res.status(201).json({ message: "User logged in successfully", succe
next()
} catch (error) {
console.error(error);
}
}

You are determining in the code above whether the email and
password match any previously stored user in the database.

Then add the following code to the file AuthRoute.js in the Routes
directory:

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 24/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

const { Signup, Login } = require('../Controllers/AuthController')


Forum Donate
const router = require('express').Router()
Support our charity and our mission. Donate to freeCodeCamp.org.
router.post('/signup', Signup)
router.post('/login', Login)

module.exports = router

Now, let's go ahead to test the application:

If you try to use an unregistered email or password , you'll get the


message below:

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 25/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

Forum Donate

Support our charity and our mission. Donate to freeCodeCamp.org.

How to Handle the HOME Route


Now, you will create a AuthMiddleware.js file, in the Middlewares
directory, and paste in the code below:

const User = require("../Models/UserModel");


require("dotenv").config();
const jwt = require("jsonwebtoken");

module.exports.userVerification = (req, res) => {


const token = req.cookies.token
if (!token) {
return res.json({ status: false })
}
jwt.verify(token, process.env.TOKEN_KEY, async (err, data) => {
if (err) {
return res.json({ status: false })
} else {
const user = await User.findById(data.id)
if (user) return res.json({ status: true, user: user.username })
else return res.json({ status: false })
}

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 26/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

})
Forum Donate
}

Support our charity and our mission. Donate to freeCodeCamp.org.

The code above checks if the user has access to the route by checking
if the token s match.

Next, update the AuthRoute.js file in the Routes directory with the
code below:

router.post('/',userVerification)

Now, you can go ahead to test your route. It should look like the image
below:

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 27/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

How to Implement the Frontend


Forum Donate

Support
To get ourgo
started, charity and client
into the our mission. Donateand
directory to freeCodeCamp.org.
install the following
in your terminal:

npm install react-cookie react-router-dom react-toastify axios

Now, update the index.js file in the client directory with the code
snippet below:

In the code above, wrapping your App component with


BrowserRouter is necessary to enable client-side routing and take
advantage of its benefits in your application.

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 28/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

NB: Remove the React.StrictMode later when you are testing


Forum the Donate
application and your data is being fetched twice.
Support our charity and our mission. Donate to freeCodeCamp.org.

Also, import react-toastify so it can be available in your application.

Now, go ahead to create the pages directory in your client


directory, which will contain the Home.jsx file, Login.jsx file,
Signup.jsx and index.js to export the components. Your folder
should look like the image below:

Now, fill the Login.jsx , Signup.jsx , and Home.jsx , respectively,


with the code below. These snippets below, are functional
components which will be modified later in this guide.

NB: This can be automatically generated by typing the shortcut rafce


+ enter in the file you want to add the snippet in your visual studio
code editor. Make sure this extension is installed in your visual studio
code for this to work.

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 29/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

Login.jsx : Forum Donate

Support our charity and our mission. Donate to freeCodeCamp.org.

import React from "react";

const Login = () => {


return <h1>Login Page</h1>;
};

export default Login

Signup.jsx :

import React from "react";

const Signup = () => {


return <h1>Signup Page</h1>;
};

export default Signup

Home.jsx :

import React from "react";

const Home = () => {


return <h1>Home PAGE</h1>;
};

export default Home

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 30/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

After that's done, you will go into the index.js file in the pages
Forum Donate
directory to export the newly created components. It should look like
Support our charity and our mission. Donate to freeCodeCamp.org.
the image below:

The method shown above makes importing components easier by


requiring only one import line.

Now, update the App.js file in the src directory with the code
below.

import { Route, Routes } from "react-router-dom";


import { Login, Signup } from "./pages";
import Home from "./pages/Home";

function App() {
return (
<div className="App">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<Signup />} />
</Routes>
</div>
);

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 31/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

}
Forum Donate
export default App;
Support our charity and our mission. Donate to freeCodeCamp.org.

The routes will be made available in your application using the above
code. The example below will help to clarify:

How to Handle the Signup Logic


In the Signup.jsx file in the pages directory, paste the following
code snippet:

import React, { useState } from "react";


import { Link, useNavigate } from "react-router-dom";
import axios from "axios";
import { ToastContainer, toast } from "react-toastify";

const Signup = () => {


const navigate = useNavigate();
const [inputValue, setInputValue] = useState({

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 32/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

email: "",
Forum Donate
password: "",
username: "",
Support our charity and our mission. Donate to freeCodeCamp.org.
});
const { email, password, username } = inputValue;
const handleOnChange = (e) => {
const { name, value } = e.target;
setInputValue({
...inputValue,
[name]: value,
});
};

const handleError = (err) =>


toast.error(err, {
position: "bottom-left",
});
const handleSuccess = (msg) =>
toast.success(msg, {
position: "bottom-right",
});

const handleSubmit = async (e) => {


e.preventDefault();
try {
const { data } = await axios.post(
"http://localhost:4000/signup",
{
...inputValue,
},
{ withCredentials: true }
);
const { success, message } = data;
if (success) {
handleSuccess(message);
setTimeout(() => {
navigate("/");
}, 1000);
} else {
handleError(message);
}
} catch (error) {
console.log(error);
}
setInputValue({
...inputValue,

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 33/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

email: "",
Forum Donate
password: "",
username: "",
Support our charity and our mission. Donate to freeCodeCamp.org.
});
};

return (
<div className="form_container">
<h2>Signup Account</h2>
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="email">Email</label>
<input
type="email"
name="email"
value={email}
placeholder="Enter your email"
onChange={handleOnChange}
/>
</div>
<div>
<label htmlFor="email">Username</label>
<input
type="text"
name="username"
value={username}
placeholder="Enter your username"
onChange={handleOnChange}
/>
</div>
<div>
<label htmlFor="password">Password</label>
<input
type="password"
name="password"
value={password}
placeholder="Enter your password"
onChange={handleOnChange}
/>
</div>
<button type="submit">Submit</button>
<span>
Already have an account? <Link to={"/login"}>Login</Link>
</span>
</form>
<ToastContainer />

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 34/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

</div>
Forum Donate
);
};
Support our charity and our mission. Donate to freeCodeCamp.org.
export default Signup;

How to Handle the Login Logic


Add the following code snippet to the Login.jsx file in the pages
directory:

import React, { useState } from "react";


import { Link, useNavigate } from "react-router-dom";
import axios from "axios";
import { ToastContainer, toast } from "react-toastify";

const Login = () => {


const navigate = useNavigate();
const [inputValue, setInputValue] = useState({
email: "",
password: "",
});
const { email, password } = inputValue;
const handleOnChange = (e) => {
const { name, value } = e.target;
setInputValue({
...inputValue,
[name]: value,
});
};

const handleError = (err) =>


toast.error(err, {
position: "bottom-left",
});
const handleSuccess = (msg) =>
toast.success(msg, {
position: "bottom-left",
});

const handleSubmit = async (e) => {


https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 35/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

e.preventDefault();
Forum Donate
try {
const { data } = await axios.post(
Support our charity and our mission. Donate to freeCodeCamp.org.
"http://localhost:4000/login",
{
...inputValue,
},
{ withCredentials: true }
);
console.log(data);
const { success, message } = data;
if (success) {
handleSuccess(message);
setTimeout(() => {
navigate("/");
}, 1000);
} else {
handleError(message);
}
} catch (error) {
console.log(error);
}
setInputValue({
...inputValue,
email: "",
password: "",
});
};

return (
<div className="form_container">
<h2>Login Account</h2>
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="email">Email</label>
<input
type="email"
name="email"
value={email}
placeholder="Enter your email"
onChange={handleOnChange}
/>
</div>
<div>
<label htmlFor="password">Password</label>
<input

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 36/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

type="password"
Forum Donate
name="password"
value={password}
Support our charity and our mission. Donate to freeCodeCamp.org.
placeholder="Enter your password"
onChange={handleOnChange}
/>
</div>
<button type="submit">Submit</button>
<span>
Already have an account? <Link to={"/signup"}>Signup</Link>
</span>
</form>
<ToastContainer />
</div>
);
};

export default Login;

How to Handle the Home Page Logic


Copy and paste the following code snippet into the Home.jsx file
located in the pages directory:

import { useEffect, useState } from "react";


import { useNavigate } from "react-router-dom";
import { useCookies } from "react-cookie";
import axios from "axios";
import { ToastContainer, toast } from "react-toastify";

const Home = () => {


const navigate = useNavigate();
const [cookies, removeCookie] = useCookies([]);
const [username, setUsername] = useState("");
useEffect(() => {
const verifyCookie = async () => {
if (!cookies.token) {
navigate("/login");
}
const { data } = await axios.post(
https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 37/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

"http://localhost:4000",
Forum Donate
{},
{ withCredentials: true }
Support our charity and our mission. Donate to freeCodeCamp.org.
);
const { status, user } = data;
setUsername(user);
return status
? toast(`Hello ${user}`, {
position: "top-right",
})
: (removeCookie("token"), navigate("/login"));
};
verifyCookie();
}, [cookies, navigate, removeCookie]);
const Logout = () => {
removeCookie("token");
navigate("/signup");
};
return (
<>
<div className="home_page">
<h4>
{" "}
Welcome <span>{username}</span>
</h4>
<button onClick={Logout}>LOGOUT</button>
</div>
<ToastContainer />
</>
);
};

export default Home;

Ensure that the styles below are copied into your index.css file:

*,
::before,
::after {
box-sizing: border-box;
padding: 0;
margin: 0;
https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 38/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

}
Forum Donate
label {
Support our charity and our mission. Donate to freeCodeCamp.org.
font-size: 1.2rem;
color: #656262;
}

html,
body {
height: 100%;
width: 100%;
}

body {
display: flex;
justify-content: center;
align-items: center;
background: linear-gradient(
90deg,
rgba(2, 0, 36, 1) 0%,
rgba(143, 187, 204, 1) 35%,
rgba(0, 212, 255, 1) 100%
);
font-family: Verdana, Geneva, Tahoma, sans-serif;
}

.form_container {
background-color: #fff;
padding: 2rem 3rem;
border-radius: 0.5rem;
width: 100%;
max-width: 400px;
box-shadow: 8px 8px 24px 0px rgba(66, 68, 90, 1);
}

.form_container > h2 {
margin-block: 1rem;
padding-block: 0.6rem;
color: rgba(0, 212, 255, 1);
}

.form_container > form {


display: flex;
flex-direction: column;
gap: 1.4rem;
}

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 39/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

Forum Donate
.form_container div {
display: flex;
Support our charity and our mission. Donate to freeCodeCamp.org.
flex-direction: column;
gap: 0.3rem;
}

.form_container input {
border: none;
padding: 0.5rem;
border-bottom: 1px solid gray;
font-size: 1.1rem;
outline: none;
}

.form_container input::placeholder {
font-size: 0.9rem;
font-style: italic;
}

.form_container button {
background-color: rgba(0, 212, 255, 1);
color: #fff;
border: none;
padding: 0.6rem;
font-size: 1rem;
cursor: pointer;
border-radius: 0.3rem;
}

span a {
text-decoration: none;
color: rgba(0, 212, 255, 1);
}

.home_page {
height: 100vh;
width: 100vw;
background: #000;
color: white;
display: flex;
justify-content: center;
align-items: center;
text-transform: uppercase;
font-size: 3rem;
flex-direction: column;

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 40/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

gap: 1rem;
Forum Donate
}

Support our charity and our mission. Donate to freeCodeCamp.org.


.home_page span {
color: rgba(0, 212, 255, 1);
}

.home_page button {
background-color: rgb(27, 73, 83);
color: #fff;
cursor: pointer;
padding: 1rem 3rem;
font-size: 2rem;
border-radius: 2rem;
transition: ease-in 0.3s;
border: none;
}

.home_page button:hover {
background-color: rgba(0, 212, 255, 1);
}

@media only screen and (max-width: 1200px){


.home_page{
font-size: 1.5rem;
}
.home_page button {
padding: 0.6rem 1rem;
font-size: 1.5rem;
}
}

I'll now quickly demonstrate everything you've learned in this article.

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 41/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

Forum Donate

Support our charity and our mission. Donate to freeCodeCamp.org.

Conclusion
In this article, you've learned how to use JWT for authentication and
authorization, helping you build secure Node.js applications.

This guide can help you guard against security threats and prevent
unauthorized access by implementing strong authentication and
authorization procedures.

FADAHUNSI SEYI SAMUEL


I'm a full-stack developer from Nigeria. I love writing about
[...Javascript_stacks]

If you read this far, thank the author to show them you care.
Say Thanks

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 42/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

Learn to code for free. freeCodeCamp's open source curriculum


Forum has Donate
helped more than 40,000 people get jobs as developers.
Support our charity and our mission. Donate to freeCodeCamp.org.
Get started
ADVERTISEMENT

freeCodeCamp is a donor-supported tax-exempt 501(c)(3) charity organization (United States


Federal Tax Identification Number: 82-0779546)

Our mission: to help people learn to code for free. We accomplish this by creating thousands of
videos, articles, and interactive coding lessons - all freely available to the public.

Donations to freeCodeCamp go toward our education initiatives, and help pay for servers,
services, and staff.

You can make a tax-deductible donation here .

Trending Guides

Learn CSS Transform Build a Static Blog Build an AI Chatbot


What is Programming? Python Code Examples Open Source for Devs
HTTP Networking in JS Write React Unit Tests Learn Algorithms in JS
How to Write Clean Code Learn PHP Learn Java

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 43/44
07/08/2024, 12:02 How to Secure Your MERN Stack App with JWT-Based User Authentication and Authorization

Learn Swift Learn Golang Learn Node.js


Forum Donate
Learn CSS Grid Learn Solidity Learn Express.js
Support our charity and our mission. Donate to freeCodeCamp.org.
Learn JS Modules Learn Apache Kafka REST API Best Practices
Front-End JS Development Learn to Build REST APIs Intermediate TS and React
Command Line for Beginners Intro to Operating Systems Learn to Build GraphQL APIs
OSS Security Best Practices Distributed Systems Patterns Software Architecture
Patterns

Mobile App

Our Charity

About Alumni Network Open Source Shop Support Sponsors Academic Honesty

Code of Conduct Privacy Policy Terms of Service Copyright Policy

https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 44/44

You might also like