{"id":70740,"date":"2025-01-28T18:37:07","date_gmt":"2025-01-28T13:07:07","guid":{"rendered":"https:\/\/www.guvi.in\/blog\/?p=70740"},"modified":"2025-04-08T15:13:34","modified_gmt":"2025-04-08T09:43:34","slug":"building-secure-authentication-by-setting-up-jwt","status":"publish","type":"post","link":"https:\/\/www.guvi.in\/blog\/building-secure-authentication-by-setting-up-jwt\/","title":{"rendered":"Building Secure Authentication by Setting Up JWT in a Node.js App"},"content":{"rendered":"\n<p>Building a secure and scalable authentication system doesn&#8217;t have to be complicated. What if you could eliminate the need for managing server-side sessions while keeping user sessions lightweight and secure?<\/p>\n\n\n\n<p>Enter <strong>JSON Web Tokens (JWT)<\/strong> \u2014 a fast, stateless, and reliable solution for user authentication. JWTs are ideal for modern web applications, from single-page apps to complex microservices architectures.<\/p>\n\n\n\n<p>In this guide, you\u2019ll learn how to set up JWT in a Node.js application from scratch &amp; create a secure login system that avoids server-side session storage.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Step 1: Project Setup \u2013 Let\u2019s Build the Foundation<\/strong><\/h2>\n\n\n\n<p>Before we jump into the coding magic, let&#8217;s set up our project.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>1.1: Initialize a Node.js Project<\/strong><\/h3>\n\n\n\n<p>First, create a new project directory and initialize a <a href=\"https:\/\/www.guvi.in\/blog\/guide-for-nodejs-as-backend\/\" target=\"_blank\" rel=\"noreferrer noopener\">Node.js<\/a> project using npm. Don\u2019t worry; it\u2019s a one-liner to get started!<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir jwt-auth-app\ncd jwt-auth-app\nnpm init \u2013y\n<\/code><\/pre>\n\n\n\n<p>This creates a package.json file that will keep track of all your dependencies.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>1.2: Install the Necessary Packages<\/strong><\/h3>\n\n\n\n<p>Now, let\u2019s install the key packages we&#8217;ll need:<\/p>\n\n\n\n<ul>\n<li>express: To build our server and handle routing.<\/li>\n\n\n\n<li>JSON web token: To create and verify JWTs.<\/li>\n<\/ul>\n\n\n\n<p>Run this command to install both:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install express jsonwebtoken<\/code><\/pre>\n\n\n\n<p>With the dependencies set up, we\u2019re ready to write some code!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Step 2: Building the Authentication Route<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>2.1: Set Up the Express Server<\/strong><\/h3>\n\n\n\n<p>Create a new file called index.js. This is where the magic begins. We\u2019ll start by setting up a basic Express server that listens on a port and can handle incoming requests.<\/p>\n\n\n\n<p>Here\u2019s the code for that:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const express = require('express');\nconst app = express();\n\n\n\/\/ Middleware to parse JSON bodies\napp.use(express.json());\n\n\nconst PORT = process.env.PORT || 3000;\napp.listen(PORT, () =&gt; {\n  console.log(`Server running on port ${PORT}`);\n});\n<\/code><\/pre>\n\n\n\n<p>With this simple server in place, we\u2019re ready to add our authentication route.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>2.2: Defining the Login Route<\/strong><\/h3>\n\n\n\n<p>Now, let\u2019s add the \/login route, which will authenticate the user based on their credentials and generate a    <a href=\"https:\/\/jwt.io\/\" data-type=\"link\" data-id=\"https:\/\/jwt.io\/\" target=\"_blank\" rel=\"noreferrer noopener\">JWT<\/a>. For simplicity, we\u2019ll use hardcoded values for username and password. But in a real-world application, you would check against a database.<\/p>\n\n\n\n<p>Here\u2019s the code for the login route:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const jwt = require('jsonwebtoken');\nconst SECRET_KEY = 'your_secret_key';  \/\/ Keep this secret in production!\n\n\napp.post('\/login', (req, res) =&gt; {\n  const { username, password } = req.body;\n\n\n  \/\/ Hardcoded credentials (replace this with actual database checks in production)\n  if (username === 'user' &amp;&amp; password === 'password') {\n    \/\/ Create a JWT with user info and an expiration time of 1 hour\n    const token = jwt.sign({ username }, SECRET_KEY, { expiresIn: '1h' });\n\n\n    \/\/ Send the token back to the user\n    res.json({ token });\n  } else {\n    res.status(401).send('Unauthorized');\n  }\n});\n\n<\/code><\/pre>\n\n\n\n<p>Here\u2019s what happens when a user hits this \/login route:<\/p>\n\n\n\n<ul>\n<li>We check if the provided username and password match our hardcoded credentials (&#8216;user&#8217; and &#8216;password&#8217;).<\/li>\n\n\n\n<li>If they match, we generate a JWT using the jwt.sign() method. The token will contain the user\u2019s username and an expiration time of 1 hour.<\/li>\n\n\n\n<li>This token is returned to the user as a JSON response.<\/li>\n<\/ul>\n\n\n\n<blockquote class=\"wp-block-quote\">\n<h3 class=\"wp-block-heading\"><strong><em>What\u2019s a JWT?<\/em><\/strong><\/h3>\n\n\n\n<p>Think of the JWT as a secure passport. It\u2019s a compact string that contains all the necessary information to verify a user\u2019s identity. Once generated, the user can use this token to access protected routes within the app without needing to log in again \u2014 as long as the token hasn\u2019t expired!<\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Step 3: Testing the Login Route<\/strong><\/h2>\n\n\n\n<p>Now that we have our login route set up, it\u2019s time to test it. You can use Postman (or any other API testing tool) to send a POST request to \/login with a username and password in the body.<\/p>\n\n\n\n<p>Here\u2019s what you do:<\/p>\n\n\n\n<ol>\n<li>Open Postman.<\/li>\n\n\n\n<li>Set the request method to POST.<\/li>\n\n\n\n<li>Enter http:\/\/localhost:3000\/login as the request URL.<\/li>\n\n\n\n<li>In the body, add the following JSON data:<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n\"username\": \"user\",\n\"password\": \"password\"\n}\n<\/code><\/pre>\n\n\n\n<p>Click Send, and if your credentials match the hardcoded ones, you\u2019ll receive a response like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n\"token\": \"your.jwt.token.here\"\n}\n<\/code><\/pre>\n\n\n\n<p>This token is your ticket to access protected resources in your app!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Step 4: Using the JWT for Protected Routes<\/strong><\/h2>\n\n\n\n<p>Once we have our JWT, we can use it to authenticate the user for future requests. For example, let\u2019s create a protected route that can only be accessed if the user provides a valid JWT.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>4.1: Create a Middleware to Verify the JWT<\/strong><\/h3>\n\n\n\n<p>Instead of verifying the JWT in each route, we can create a middleware that will handle the token verification. This way, we can reuse the middleware for any route that requires authentication.<\/p>\n\n\n\n<p>Here\u2019s how you can structure the middleware:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Middleware to verify JWT\nconst jwt = require('jsonwebtoken');\nconst SECRET_KEY = 'your_secret_key'; \/\/ Make sure to use an environment variable in production!\n\n\nfunction verifyToken(req, res, next) {\n  const token = req.header('Authorization')?.replace('Bearer ', ''); \/\/ Get token from Authorization header\n  \n  if (!token) {\n    return res.status(401).send('Access Denied: No token provided');\n  }\n\n\n  try {\n    \/\/ Verify the token using jwt.verify and decode it\n    const decoded = jwt.verify(token, SECRET_KEY);\n    \n    \/\/ Attach the decoded user info to the request object for use in subsequent route handlers\n    req.user = decoded;\n    \n    \/\/ Proceed to the next middleware or route handler\n    next();\n  } catch (error) {\n    res.status(400).send('Invalid Token');\n  }\n}\n\n\nmodule.exports = verifyToken; \/\/ Export the middleware\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>4.2: Use the Middleware in the \/protected Route<\/strong><\/h3>\n\n\n\n<p>Now that you have the verifyToken middleware, use it in the \/protected route. This will ensure that only authenticated users can access the protected resource.<\/p>\n\n\n\n<p>Here\u2019s how to modify your code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const verifyToken = require('.\/verifyToken'); \/\/ Import the middleware\n\n\n\/\/ Protected route using the verifyToken middleware\napp.get('\/protected', verifyToken, (req, res) =&gt; {\n  \/\/ If we reached this point, it means the token is valid\n  res.send(`Welcome to the protected route, ${req.user.username}!`);\n});\n\n\napp.listen(PORT, () =&gt; {\n  console.log(`Server running on port ${PORT}`);\n});\n<\/code><\/pre>\n\n\n\n<p><strong>Step 5: Testing the Protected Route<\/strong><\/p>\n\n\n\n<p>To test the \/protected route, follow these steps:<\/p>\n\n\n\n<p>Login: Send a POST request to \/login with the credentials in the request body:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"username\": \"user\",\n  \"password\": \"password\"\n}<\/code><\/pre>\n\n\n\n<p>If the credentials are valid, you will receive a JWT token in the response:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"token\": \"your.jwt.token.here\"\n}\n<\/code><\/pre>\n\n\n\n<p>Access Protected Route: To access the \/protected route, send a GET request to \/protected with the token in the Authorization header as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Authorization: Bearer your.jwt.token.here<\/code><\/pre>\n\n\n\n<p>If the token is valid, the response will be:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Welcome to the protected route, user!<\/code><\/pre>\n\n\n\n<p><em><strong>Also Explore<\/strong><\/em>: <a href=\"https:\/\/www.guvi.in\/blog\/new-array-and-object-methods-in-javascript\/\" target=\"_blank\" rel=\"noreferrer noopener\">Exploring the New Array and Object Methods in JavaScript<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Benefits of This Approach<\/strong><\/h2>\n\n\n\n<ul>\n<li><strong>Code Reusability:<\/strong> The verifyToken middleware can be reused across all routes that require authentication, making your code DRY (Don&#8217;t Repeat Yourself).<\/li>\n<\/ul>\n\n\n\n<ul>\n<li><strong>Security:<\/strong> The JWT verification is centralized in one place. If you need to change the verification logic, you can do it in the middleware rather than in each route.<\/li>\n<\/ul>\n\n\n\n<ul>\n<li><strong>Clarity:<\/strong> By using middleware, you can easily separate concerns \u2014 authentication handling is in the middleware, while route logic remains focused on the actual functionality.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Next Steps<\/strong><\/h3>\n\n\n\n<ul>\n<li><strong>Store Secret Keys Securely:<\/strong> Always use environment variables for sensitive information like the SECRET_KEY. You can use packages like dotenv to load them from .env files in development.<\/li>\n<\/ul>\n\n\n\n<ul>\n<li><strong>Refresh Tokens:<\/strong> If you&#8217;d like users to remain logged in for a longer period, you can implement refresh tokens, which are securely stored and used to get a new access token when the old one expires.<\/li>\n<\/ul>\n\n\n\n<p>JWTs are a crucial part of modern web security, and by implementing them in your application, you\u2019re taking a significant step toward building a robust and scalable system.<\/p>\n\n\n\n<p><em>Unlock your potential as a Java Full-Stack Developer with our comprehensive <a href=\"https:\/\/www.guvi.in\/zen-class\/full-stack-development-course\/?utm_source=blog&amp;utm_medium=organic&amp;utm_campaign=Building+Secure+Authentication+by+Setting+Up+JWT+in+a+Node.js+App\" target=\"_blank\" data-type=\"link\" data-id=\"https:\/\/www.guvi.in\/zen-class\/full-stack-development-course\/?utm_source=blog&amp;utm_medium=organic&amp;utm_campaign=Building+Secure+Authentication+by+Setting+Up+JWT+in+a+Node.js+App\" rel=\"noreferrer noopener\">Java Full-Stack development course<\/a>! Dive deep into the world of Java, mastering front-end and back-end development to build powerful, dynamic web applications. Gain hands-on experience with essential tools and frameworks like Spring Boot, Hibernate, Angular, and React, all while learning best practices for performance optimization and scalable coding. Start your journey today and become the all-in-one developer every company is searching for!<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Wrapping Up<\/strong><\/h2>\n\n\n\n<p>By implementing JWT in your Node.js application, you\u2019ve built a secure, scalable authentication system that\u2019s lightweight and efficient. With reusable middleware and protected routes, your app is now equipped to handle user authentication with modern best practices.<\/p>\n\n\n\n<p>Take it further by securing sensitive keys, adding refresh tokens, and exploring advanced authentication features to enhance your system\u2019s robustness. You&#8217;re now one step closer to building secure and scalable web applications!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Frequently Asked Questions<\/h2>\n\n\n<div id=\"rank-math-faq\" class=\"rank-math-block\">\n<div class=\"rank-math-list \">\n<div id=\"faq-question-1738055161492\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \"><strong>1. What is the role of JWT in a Node.js app?<\/strong><\/h3>\n<div class=\"rank-math-answer \">\n\n<p>JWTs play a crucial role in enabling secure and stateless authentication in Node.js apps. Instead of maintaining server-side sessions, JWTs store user information in a compact signed token that the client sends with each request. This reduces server overhead and allows scalable authentication systems.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1738055243082\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \">2. <strong>How can I handle JWT expiration in my app?<\/strong><\/h3>\n<div class=\"rank-math-answer \">\n\n<p>When a JWT expires, you can prompt the user to log in again or use refresh tokens to generate a new JWT. Refresh tokens are long-lived and allow for seamless re-authentication without asking users to log in repeatedly.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1738055285515\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \">3. Is JWT the best choice for every authentication scenario?<\/h3>\n<div class=\"rank-math-answer \">\n\n<p>JWT is excellent for stateless authentication in APIs and microservices. However, for applications requiring high security or stateful interactions, traditional session-based authentication may be a better fit. Choose based on your app&#8217;s requirements.<\/p>\n\n<\/div>\n<\/div>\n<\/div>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>Building a secure and scalable authentication system doesn&#8217;t have to be complicated. What if you could eliminate the need for managing server-side sessions while keeping user sessions lightweight and secure? Enter JSON Web Tokens (JWT) \u2014 a fast, stateless, and reliable solution for user authentication. JWTs are ideal for modern web applications, from single-page apps [&hellip;]<\/p>\n","protected":false},"author":46,"featured_media":70851,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[907,429],"tags":[],"views":"3574","authorinfo":{"name":"Poonam Chauhan","url":"https:\/\/www.guvi.in\/blog\/author\/poonam-chauhan\/"},"thumbnailURL":"https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2025\/01\/JWT-300x112.webp","jetpack_featured_media_url":"https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2025\/01\/JWT.webp","_links":{"self":[{"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/posts\/70740"}],"collection":[{"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/users\/46"}],"replies":[{"embeddable":true,"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/comments?post=70740"}],"version-history":[{"count":8,"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/posts\/70740\/revisions"}],"predecessor-version":[{"id":78279,"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/posts\/70740\/revisions\/78279"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/media\/70851"}],"wp:attachment":[{"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/media?parent=70740"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/categories?post=70740"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/tags?post=70740"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}