Skip to main content

Command Palette

Search for a command to run...

JWT Authentication in Node.js Explained Simply

Updated
3 min readView as Markdown

What Authentication Means

Authentication is the process of verifying who a user is.

When a user logs in:

  • They provide credentials (like email + password)

  • The server checks if those credentials are valid

  • If valid → the user is authenticated

Think of it like logging into your phone:

  • Password correct → access granted

  • Password wrong → access denied

What is JWT?

JWT (JSON Web Token) is a compact, secure way to transmit information between client and server.

Instead of storing session data on the server, JWT allows:

  • Stateless authentication

  • Scalable backend systems

A JWT is basically:

A signed token that proves the user is authenticated

Structure of a JWT

A JWT has 3 parts, separated by dots:

xxxxx.yyyyy.zzzzz

Contains metadata about the token:

{
  "alg": "HS256",
  "typ": "JWT"
}
  • alg → algorithm used for signing

  • typ → token type

Contains actual data (claims):

{ "userId": "123", "email": "user@example.com" }

Payload

Contains actual data (claims):

{
  "userId": "123",
  "email": "user@example.com"
}

⚠️ Important:

  • This is NOT encrypted, only encoded

  • Do NOT store sensitive data (like passwords)

Signature

Used to verify token integrity:

HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)
  • Ensures token hasn’t been tampered with

  • Generated using a secret key

Login Flow Using JWT

Here’s how authentication works in practice:

Step 1: User logs in

Client sends:

POST /login

With:

{
  "email": "user@example.com",
  "password": "123456"
}

Step 2: Server verifies credentials

If valid:

  • Server creates a JWT

  • Signs it using a secret

Example:

const jwt = require("jsonwebtoken");

const token = jwt.sign(
  { userId: user._id },
  "your_secret_key",
  { expiresIn: "1h" }
);

Step 3: Token sent to client

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Client stores it:

  • LocalStorage / SessionStorage / Cookie

Sending Token with Requests

For protected routes, the client must send the token.

Usually via HTTP headers:

Authorization: Bearer <token>

Example using fetch:

fetch("/profile", {
  headers: {
    Authorization: `Bearer ${token}`
  }
});

Protecting Routes Using Tokens

In Node.js (Express), you verify the token using middleware.

Middleware Example

const jwt = require("jsonwebtoken");

function authMiddleware(req, res, next) {
  const authHeader = req.headers.authorization;

  if (!authHeader) {
    return res.status(401).json({ message: "No token provided" });
  }

  const token = authHeader.split(" ")[1];

  try {
    const decoded = jwt.verify(token, "your_secret_key");
    req.user = decoded;
    next();
  } catch (err) {
    return res.status(401).json({ message: "Invalid token" });
  }
}

Using Middleware

app.get("/profile", authMiddleware, (req, res) => {
  res.json({
    message: "Protected data",
    user: req.user
  });
});