Learn Infotech
February 9, 2025
Nodejs

0 likes


JWT Authentication in Node.js: Everything You Need to Know

Hello welcome! Today we'll be looking at JWT authentication, what it is? why it is used for and everything we need to know.

Authentication is a crucial part of any web application, ensuring that users can securely access their accounts and data. One of the most popular authentication methods today is JSON Web Tokens (JWT). We'll dive deep into JWT authentication in Node.js, explaining how it works, its benefits, and how you can implement it in your application.

What is JWT?

JWT (JSON Web Token) is a compact and self-contained way of securely transmitting information between parties as a JSON object. It is often used for authentication and authorization in web applications.

A JWT consists of three parts:

  1. Header – Contains metadata about the token, including the signing algorithm.

  2. Payload – Contains user information and other claims.

  3. Signature – A cryptographic signature that ensures the token hasn’t been tampered with.

A sample JWT looks like this:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNjUxMjM0NTY3LCJleHAiOjE2NTEyMzgxNjd9.LhYKKO8YqTAS67Y9qSOKGOUr4IU1DJYq5S5U1AMOQyU

Notice the three parts separated by dots.

  • "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9" contains Header information.

  • "eyJ1c2VySWQiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNjUxMjM0NTY3LCJleHAiOjE2NTEyMzgxNjd9" contains the payload,

  • "LhYKKO8YqTAS67Y9qSOKGOUr4IU1DJYq5S5U1AMOQyU" contains the signature.

You can check header and payload of your token in https://jwt.io . It will look something the in picture below.

So then why do we use JWT for Authentication?

  • Stateless: Unlike traditional session-based authentication, JWT does not require the server to store session information, making it scalable.

  • Secure: When properly implemented, JWT can be a secure way to authenticate users.

  • Compact: The token is small and can be easily included in HTTP headers.

  • Cross-domain support: JWT can be used in single sign-on (SSO) across multiple domains.

How JWT Authentication Works

  1. User Logs In: The user provides their credentials (username and password).

  2. Server Verifies Credentials: The server checks if the credentials are correct by checking the database.

  3. JWT is Issued: If user is valid, the server generates a JWT and sends it back to the client.

  4. Client Stores Token: The client stores the token (usually in local Storage or a cookie).

  5. Client Makes Requests with JWT: The client includes the token in the Authorization header for other request like profile, blogs and so on.

  6. Server Verifies JWT: The server then validates the token and then only give access to the user.

So let's dive In and Implement JWT Authentication in Node.js

Step 1: Setting Up the Project

First, initialize a Node.js project and install the required dependencies:

mkdir jwt-auth-backend && cd jwt-auth-backend
npm init -y
npm install express jsonwebtoken dotenv bcryptjs cors body-parser

Step 2: Creating the Server

Create an index.js file and set up a basic Express server:

const express = require('express');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const dotenv = require('dotenv');
const bodyParser = require('body-parser');

dotenv.config();
const app = express();
app.use(bodyParser.json());

const users = []; // Simulating a database
const SECRET_KEY = process.env.SECRET_KEY || 'your_secret_key';

const isAuthenticated=(req,res,next)=>{
    const authHeader = req.headers['authorization'];
    if (!authHeader) return res.sendStatus(401);
    const token = authHeader.split(' ')[1];
    jwt.verify(token, SECRET_KEY, (err, user) => {
        if (err) return res.sendStatus(403);
        next();
    });
});

// Register Route
app.post('/register', async (req, res) => {
    const { username, password } = req.body;
    const hashedPassword = await bcrypt.hash(password, 10);
    users.push({ username, password: hashedPassword });
    res.json({ message: 'User registered successfully!' });
});

// Login Route
app.post('/login', async (req, res) => {
    const { username, password } = req.body;
    const user = users.find(u => u.username === username);
    if (!user || !(await bcrypt.compare(password, user.password))) {
        return res.status(401).json({ message: 'Invalid credentials' });
    }
    const token = jwt.sign({ username }, SECRET_KEY, { expiresIn: '1h' });
    res.json({ token });
});

// Protected Route
app.get('profile',isAuthenticated,(req,res)=>{
   res.json({message:"profile is accessed"});
});

app.listen(3000, () => console.log('Server running on port 3000'));

Here we have used users array to push user's info while registering to simulate like a database. Be free to use your own preferred database like mongodb, mysql or postgresql.

The profile route can only be accessed with the token provided which is checked by using a middleware called isAuthenticated.

Step 3: Now we test the APIs (Note: You can use postman for testing purpose)

  1. Register a User:

    curl -X POST http://localhost:3000/register -H "Content-Type: application/json" -d '{"username":"user1","password":"password123"}'
  2. Login to Get a Token:

    curl -X POST http://localhost:3000/login -H "Content-Type: application/json" -d '{"username":"user1","password":"password123"}'

    Response:

    { "token": "your_jwt_token" }
  3. Access Protected Route (Replace your_jwt_token with the actual token from login response):

    curl -X GET http://localhost:3000/profile -H "Authorization: Bearer your_jwt_token"

We are using Bearer token which is industry standard practice.

Best Practices for Using JWT

  1. Keep Your Secret Key Safe: Store it in environment variables and never hardcode it.

  2. Use HTTPS: Always send JWTs over HTTPS to prevent interception.

  3. Set Expiry Time: Tokens should expire to prevent misuse.

  4. Use Refresh Tokens: For long-lived sessions, implement refresh tokens instead of extending access tokens.

  5. Avoid Storing JWT in Local Storage: Use HttpOnly cookies instead to prevent XSS attacks.

Conclusion

JWT authentication in Node.js is a powerful and secure method for handling authentication. You can implement it in your applications while ensuring security best practices are met.

Try to integrate JWT authentication with a database like MongoDB or PostgreSQL in your application!

Happy coding! 🚀

Learn Infotech
Managed by Suprince Shakya