How To Secure Your MERN Stack App With JWT-Based User Authentication and Authorization
How To Secure Your MERN Stack App With JWT-Based User Authentication and Authorization
Forum Donate
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.
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
Conclusion
Support our charity and our mission. Donate to freeCodeCamp.org.
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.
Forum Donate
Let's talk about the various elements of the MERN stack before we
start creating the authentication mechanism.
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
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
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
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
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!
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.
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.
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
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
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 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
Once you're done with this, go into your index.js in your server
directory, and update it with the code below:
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 .
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
},
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(),
},
});
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.
require("dotenv").config();
const jwt = require("jsonwebtoken");
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:
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 .
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:
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);
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
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
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
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
module.exports = router
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
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
}
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
Support
To get ourgo
started, charity and client
into the our mission. Donateand
directory to freeCodeCamp.org.
install the following
in your terminal:
Now, update the index.js file in the client directory with the code
snippet below:
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
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
Signup.jsx :
Home.jsx :
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:
Now, update the App.js file in the src directory with the code
below.
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:
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,
});
};
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;
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>
);
};
"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 />
</>
);
};
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);
}
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
}
.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);
}
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
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.
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
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.
Trending Guides
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
Mobile App
Our Charity
About Alumni Network Open Source Shop Support Sponsors Academic Honesty
https://www.freecodecamp.org/news/how-to-secure-your-mern-stack-application/ 44/44