search
HomeWeb Front-endJS TutorialMastering Secure Authentication in Node.js: Login/Logout with bcrypt.js and JWT

Imagine you’re building a web application that's about to launch. You've carefully designed the user interface, added exciting features, and made sure everything runs smoothly. But as the launch date gets closer, a nagging concern starts to worry you—security. Specifically, how to ensure that only the right users can access the right parts of your application. This is where authentication comes in.

Authentication is the process of verifying who a user is, and it's a critical aspect of web development. In the vast digital landscape, ensuring that users can securely log in and log out of your application is paramount. One slip, and your app could be vulnerable to attacks, putting user data at risk.

Introduction

In this article, we will explore secure authentication in Node.js, using bcrypt.js to hash passwords and JWT tokens to manage user sessions. By the end, you'll have a solid understanding of how to implement a strong login/logout system, keeping your users’ data safe and secure.

So, let’s embark on this journey to build a bulletproof authentication system, starting from setting up our environment to securing our routes with JWT. Ready to lock down your Node.js app? Let’s get started.

Setting Up Your Node.js Project Environment

First, initialize your Node.js project with npm init -y, which creates a package.json file with default settings. Next, install essential packages: express for setting up the server, mongoose for managing MongoDB, jsonwebtoken for handling JWT tokens, bcryptjs for hashing passwords, dotenv for environment variables, cors for enabling Cross-Origin Resource Sharing, cookie-parser for parsing cookies. Finally, add nodemon as a development dependency to automatically restart the server when code changes.

1.`npm init -y`
2.`npm install express mongoose jsonwebtoken bcryptjs dotenv cors cookie-parser`
3.`npm install nodemon -D`

Now modify the package.json file. Add scripts like my code and type.

"scripts": {
    "dev": "nodemon backend/index.js",
    "start": "node backend/index.js"
  },
"type": "module",

Basic Server Setup

Next, we'll set up a basic Express server. Create a file named index.js . This code initializes Express and creates an instance of the application. We'll then define a route for the root URL ("/") to handle incoming HTTP GET requests. After that, we'll start the server on port 8000, allowing it to listen for incoming requests.

import express from "express";
const app = express();

app.get("/", (req, res) => {
  res.send("Server is ready");
});

app.listen(8000, () => {
  console.log("Server is running on PORT 8000");
});

Setting Up Basic Authentication Routes

Now, we will create a folder named 'routes' and in that folder we will make make a new file named authRoute.js and paste the below code to see basics of routes.

In this code snippet, we're setting up routes for different authentication endpoints using Express. First, we import the express library and create a new router instance. Then, we define three GET routes: /signup, /login, and /logout, each responding with a JSON object indicating that the respective endpoint was hit. Finally, we export the router instance as the default export, making it available for use in other parts of the application.

1.`npm init -y`
2.`npm install express mongoose jsonwebtoken bcryptjs dotenv cors cookie-parser`
3.`npm install nodemon -D`

Now change the index.js adding the auth route to test out your end points.

"scripts": {
    "dev": "nodemon backend/index.js",
    "start": "node backend/index.js"
  },
"type": "module",

Now, you can test it in your browser...but I will use Postman for its convenience. You can test all the end points like this.

Mastering Secure Authentication in Node.js: Login/Logout with bcrypt.js and JWT

Similarly you can see the other routes like Logout and SignUp.

So, Our basic app is ready...now make it a robust and a proper authentication system.

Creating the User Model with Mongoose Schema

Now, first ready our mongoDB database. To do that make a folder Model and under that a file User.js and in this file add Mongoose schema and model for a User in a mongoDB database. The schema includes fields for username, fullName, password, and email, each with specified data types and constraints like uniqueness and required status. The password field also has a minimum length of 6 characters.

import express from "express";
const app = express();

app.get("/", (req, res) => {
  res.send("Server is ready");
});

app.listen(8000, () => {
  console.log("Server is running on PORT 8000");
});

Connecting to MongoDB with Mongoose

Now let's connect to our database. We'll create a folder named db and inside it, a file called connectDB.js. In this file, we'll define an asynchronous function connectMongoDB that tries to connect to a MongoDB database using Mongoose. It gets the database connection string from the MONGO_URI environment variable. If the connection is successful, it logs a success message with the host name. If it fails, it logs the error and exits the process with a status code of 1. The function is exported for use in other parts of the application.

import express from "express";

// Create a new Express router instance
const router = express.Router();

// Define a GET route for the signup endpoint
router.get("/signup", (req, res) => {
  // Return a JSON response indicating that the signup endpoint was hit
  res.json({
    data: "You hit signup endpoint",
  });
});

// Define a GET route for the login endpoint
router.get("/login", (req, res) => {
  // Return a JSON response indicating that the login endpoint was hit
  res.json({
    data: "You hit login endpoint",
  });
});

// Define a GET route for the logout endpoint
router.get("/logout", (req, res) => {
  // Return a JSON response indicating that the logout endpoint was hit
  res.json({
    data: "You hit logout endpoint",
  });
});

// Export the router instance as the default export
export default router;

Now to use MONGO_URI we have to make it in .env file. Here I have used local mongoDB setup connection string. If you want then you can also use mongoDB atlas.

import express from "express";
import authRoute from "./routes/authRoutes.js";
const app = express();

app.get("/", (req, res) => {
  res.send("Server is ready");
});

app.use("/api/auth", authRoute);

app.listen(8000, () => {
  console.log("Server is running on PORT 8000");
});

Signup function

Now make the signup function. For this 1st make a folder controller and there file authController.js

import mongoose from "mongoose";

// Define the User schema with various fields and their data types
const userSchema = new mongoose.Schema(
  {
    // The unique username of the user
    username: {
      type: String,
      required: true,
      unique: true,
    },
    fullName: {
      type: String,
      required: true,
    },
    // The password of the user (min length: 6)
    password: {
      type: String,
      required: true,
      minLength: 6,
    },
    // The email of the user (unique)
    email: {
      type: String,
      required: true,
      unique: true,
    },
  },
  { timestamps: true }
);

// Create the User model based on the userSchema
const User = mongoose.model("User", userSchema);

// Export the User model
export default User;

First, it extracts fullName, username, email, and password from the request body. It validates the email format using a regular expression, returning a 400 status if the format is invalid.

Next, the function checks if the username or email already exists in the database. If either is taken, a 400 status with an error message is returned. It also ensures the password is at least 6 characters long, sending another 400 status if this condition isn't met.

The password is then securely hashed using bcrypt. A new User instance is created with the provided data and saved to the database.

After saving, the function generates a JWT token, sets it as a cookie, and returns a 201 status with the user's ID, full name, username, and email. If any errors occur, they are logged, and a 500 status is sent with an "Internal Server Error" message.

To make this function active you have to import these

1.`npm init -y`
2.`npm install express mongoose jsonwebtoken bcryptjs dotenv cors cookie-parser`
3.`npm install nodemon -D`

Notice something? a new thing called generateTokenAndSetCookie...lets see its code...make a folder utils and there generateTokenAndSetCookie.js.

"scripts": {
    "dev": "nodemon backend/index.js",
    "start": "node backend/index.js"
  },
"type": "module",

The **generateTokenAndSetCookie **function creates a JWT and stores it in a cookie for user authentication.

JWT Generation:

The function uses the jsonwebtoken library to create a JWT. It signs the token with the user's ID and a secret key (JWT_SECRET from the environment variables), setting it to expire in 15 days.

Setting the Cookie:

The token is then stored in a cookie on the user's browser. The cookie is configured with several security attributes:

  • maxAge: Sets the cookie's lifespan to 15 days.
  • httpOnly: Ensures the cookie is not accessible via JavaScript, protecting against XSS (Cross-Site Scripting) attacks.
  • sameSite: "strict": Prevents CSRF (Cross-Site Request Forgery) attacks by restricting the cookie to be sent only with requests from the same site.
  • secure: Ensures the cookie is only sent over HTTPS if the environment is not development, adding an extra layer of security.

So this function ensures that the user's session is both secure and persistent, making it a crucial part of the authentication process.

Here we have to add another environment variable JWT_SECRET in .env. You can add any type of mix of number and string like this.

import express from "express";
const app = express();

app.get("/", (req, res) => {
  res.send("Server is ready");
});

app.listen(8000, () => {
  console.log("Server is running on PORT 8000");
});

Now our signUp function is complete..so make its route now.

import express from "express";

// Create a new Express router instance
const router = express.Router();

// Define a GET route for the signup endpoint
router.get("/signup", (req, res) => {
  // Return a JSON response indicating that the signup endpoint was hit
  res.json({
    data: "You hit signup endpoint",
  });
});

// Define a GET route for the login endpoint
router.get("/login", (req, res) => {
  // Return a JSON response indicating that the login endpoint was hit
  res.json({
    data: "You hit login endpoint",
  });
});

// Define a GET route for the logout endpoint
router.get("/logout", (req, res) => {
  // Return a JSON response indicating that the logout endpoint was hit
  res.json({
    data: "You hit logout endpoint",
  });
});

// Export the router instance as the default export
export default router;

ok, now let’s modify our index.js Here we added some new imports. dotenv: Loads environment variables securely from .env; express.json(): Parses incoming JSON requests; express.urlencoded({ extended: true }): Parses URL-encoded data; cookieParser: Handles cookies for JWT tokens; connectMongoDB(): Connects to MongoDB for data storage; Routes: /api/auth manages signup, login, and logout.

Here is updated code of index.js

1.`npm init -y`
2.`npm install express mongoose jsonwebtoken bcryptjs dotenv cors cookie-parser`
3.`npm install nodemon -D`

So. now it’s time to test our signup function in Postman. Let’s see if it’s working or not.

So, here is the results.

Mastering Secure Authentication in Node.js: Login/Logout with bcrypt.js and JWT

Here you can see it’s working properly and you can check it your mongoDB database as well.

Mastering Secure Authentication in Node.js: Login/Logout with bcrypt.js and JWT

Login function

Now make the login function. Let’s go again to our authController.js file

"scripts": {
    "dev": "nodemon backend/index.js",
    "start": "node backend/index.js"
  },
"type": "module",

The login controller authenticates a user by verifying their username and password. It first searches for the user in the database using the username. If found, it compares the provided password with the hashed password stored in the database using bcrypt. If the username or password is incorrect, it returns an error response. On successful verification, it generates a JWT token, sets it as a cookie using generateTokenAndSetCookie, and responds with a success message, indicating the user is logged in successfully.

Let’s add our login route in authRoutes.js

import express from "express";
const app = express();

app.get("/", (req, res) => {
  res.send("Server is ready");
});

app.listen(8000, () => {
  console.log("Server is running on PORT 8000");
});

Let’s test it in Postman.

Mastering Secure Authentication in Node.js: Login/Logout with bcrypt.js and JWT
Here you can see it is successfully showing Logged in.

Logout function

Okay. Now the last function i.e. the logout function. Let’s implement this. It’s pretty simple.

import express from "express";

// Create a new Express router instance
const router = express.Router();

// Define a GET route for the signup endpoint
router.get("/signup", (req, res) => {
  // Return a JSON response indicating that the signup endpoint was hit
  res.json({
    data: "You hit signup endpoint",
  });
});

// Define a GET route for the login endpoint
router.get("/login", (req, res) => {
  // Return a JSON response indicating that the login endpoint was hit
  res.json({
    data: "You hit login endpoint",
  });
});

// Define a GET route for the logout endpoint
router.get("/logout", (req, res) => {
  // Return a JSON response indicating that the logout endpoint was hit
  res.json({
    data: "You hit logout endpoint",
  });
});

// Export the router instance as the default export
export default router;

The logout controller securely logs out a user by clearing the JWT cookie from the client's browser using res.cookie, setting its value to an empty string and its maxAge to 0, ensuring immediate expiration. Upon successful cookie clearance, it sends a success response with a message indicating the user is logged out successfully. If any error occurs during this process, it catches the error, logs it, and returns an Internal Server Error response.

Add this route to our authRoute.js

import express from "express";
import authRoute from "./routes/authRoutes.js";
const app = express();

app.get("/", (req, res) => {
  res.send("Server is ready");
});

app.use("/api/auth", authRoute);

app.listen(8000, () => {
  console.log("Server is running on PORT 8000");
});

okay. Let’s test our last feature, if it’s working fine or not.

Mastering Secure Authentication in Node.js: Login/Logout with bcrypt.js and JWT

Oh!…It’s working super fine. ??

So, now our complete backend of this authentication is ready. ??

My npm package

If you don't want to code everything yourself and want a quick solution, I have created an npm package called auth0_package. You can get it from here.

Github Repository

You can get my all above code here in this github repo here.

Now your backend application is complete. In the next blog, I will explain how to integrate this with your frontend. So stay tuned for that ??.

Conclusion

In conclusion, implementing secure authentication in a Node.js application is crucial for protecting user data and ensuring that only authorized users can access specific parts of your application. By using bcrypt.js for password hashing and JWT tokens for session management, you can create a robust login/logout system. This approach not only enhances security but also provides a seamless user experience. Setting up a MongoDB database and using Express for routing further strengthens the backend infrastructure. With these tools and techniques, you can confidently launch your web application, knowing that it is well-protected against unauthorized access and potential security threats.

The above is the detailed content of Mastering Secure Authentication in Node.js: Login/Logout with bcrypt.js and JWT. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Replace String Characters in JavaScriptReplace String Characters in JavaScriptMar 11, 2025 am 12:07 AM

Detailed explanation of JavaScript string replacement method and FAQ This article will explore two ways to replace string characters in JavaScript: internal JavaScript code and internal HTML for web pages. Replace string inside JavaScript code The most direct way is to use the replace() method: str = str.replace("find","replace"); This method replaces only the first match. To replace all matches, use a regular expression and add the global flag g: str = str.replace(/fi

Build Your Own AJAX Web ApplicationsBuild Your Own AJAX Web ApplicationsMar 09, 2025 am 12:11 AM

So here you are, ready to learn all about this thing called AJAX. But, what exactly is it? The term AJAX refers to a loose grouping of technologies that are used to create dynamic, interactive web content. The term AJAX, originally coined by Jesse J

10 jQuery Fun and Games Plugins10 jQuery Fun and Games PluginsMar 08, 2025 am 12:42 AM

10 fun jQuery game plugins to make your website more attractive and enhance user stickiness! While Flash is still the best software for developing casual web games, jQuery can also create surprising effects, and while not comparable to pure action Flash games, in some cases you can also have unexpected fun in your browser. jQuery tic toe game The "Hello world" of game programming now has a jQuery version. Source code jQuery Crazy Word Composition Game This is a fill-in-the-blank game, and it can produce some weird results due to not knowing the context of the word. Source code jQuery mine sweeping game

How do I create and publish my own JavaScript libraries?How do I create and publish my own JavaScript libraries?Mar 18, 2025 pm 03:12 PM

Article discusses creating, publishing, and maintaining JavaScript libraries, focusing on planning, development, testing, documentation, and promotion strategies.

jQuery Parallax Tutorial - Animated Header BackgroundjQuery Parallax Tutorial - Animated Header BackgroundMar 08, 2025 am 12:39 AM

This tutorial demonstrates how to create a captivating parallax background effect using jQuery. We'll build a header banner with layered images that create a stunning visual depth. The updated plugin works with jQuery 1.6.4 and later. Download the

How do I optimize JavaScript code for performance in the browser?How do I optimize JavaScript code for performance in the browser?Mar 18, 2025 pm 03:14 PM

The article discusses strategies for optimizing JavaScript performance in browsers, focusing on reducing execution time and minimizing impact on page load speed.

Getting Started With Matter.js: IntroductionGetting Started With Matter.js: IntroductionMar 08, 2025 am 12:53 AM

Matter.js is a 2D rigid body physics engine written in JavaScript. This library can help you easily simulate 2D physics in your browser. It provides many features, such as the ability to create rigid bodies and assign physical properties such as mass, area, or density. You can also simulate different types of collisions and forces, such as gravity friction. Matter.js supports all mainstream browsers. Additionally, it is suitable for mobile devices as it detects touches and is responsive. All of these features make it worth your time to learn how to use the engine, as this makes it easy to create a physics-based 2D game or simulation. In this tutorial, I will cover the basics of this library, including its installation and usage, and provide a

Auto Refresh Div Content Using jQuery and AJAXAuto Refresh Div Content Using jQuery and AJAXMar 08, 2025 am 12:58 AM

This article demonstrates how to automatically refresh a div's content every 5 seconds using jQuery and AJAX. The example fetches and displays the latest blog posts from an RSS feed, along with the last refresh timestamp. A loading image is optiona

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.