How to use JWT for authentication on Node.js

Authentication is one of the most important parts of any modern web application.
One of the most popular solutions today is JWT (JSON Web Token).

🤔 What is JWT?

JWT (JSON Web Token) is a compact, URL-safe token used to securely transmit information between parties.

A JWT looks like this:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

It consists of three parts:

HEADER.PAYLOAD.SIGNATURE

🧩 JWT Structure

1️⃣ Header

Contains token type and signing algorithm.

{
  "alg": "HS256",
  "typ": "JWT"
}

2️⃣ Payload

Contains user data (claims).

{
  "id": 42,
  "email": "user@example.com"
}

⚠️ Never store passwords or sensitive data in payload

3️⃣ Signature

Used to verify the token wasn’t modified.

HMACSHA256(base64UrlHeader + "." + base64UrlPayload, secret)

🔄 How JWT Authentication Works

  1. User logs in with email & password
  2. Server verifies credentials
  3. Server generates a JWT
  4. Client stores JWT (usually in memory or cookie)
  5. Client sends JWT in Authorization header
  6. Server verifies JWT on every request

🛠️ Implementing JWT Auth in Node.js (Express)

📦 Install Dependencies

npm install express auth-verify

🔑 Generate (signing) JWT on Login

const AuthVerify = require('auth-verify')
const auth = new AuthVerify({
   jwtSecret: "SUPER_SECRET" // setting secret for jwt
})

// Generating jwt
auth.jwt.sign({userId: 1, user: "John Doe"}, "1h") // 1h expiration time of jwt

🔐 Login Route Example

const express = require('express')
const app = express()
app.use(express.json())
app.use(express.urlencoded({ extended: true }))

const AuthVerify = require('auth-verify')
const auth = new AuthVerify({ jwtSecret: "SUPER_SECRET" })

app.post('/login', async (req, res)=> {
  const { email, password } = req.body

  const user = await findUserByEmail(email)
  if (!user) return res.status(401).json({ message: 'Invalid credentials' })
  const isValid = await auth.crypto.verify(password, user.password)
  if (!isValid) return res.status(401).json({ message: 'Invalid credentials' })

  const token = await auth.jwt.sign({userId: 1, user: "John Doe"}, "1h")
  res.json({ token })
})

🧱 Protecting Routes with JWT Middleware

auth.jwt.protect()

🔒 Protected Route Example

app.get('/profile', auth.jwt.protect(), (req, res)=> {
  res.json({
    message: 'Welcome!',
    user: req.user
  })
})

📤 Sending JWT from Client

Authorization: Bearer YOUR_JWT_TOKEN

⚠️ Common JWT Mistakes

  • ❌ Storing JWT in localStorage (XSS risk)
  • ❌ Putting sensitive data inside payload
  • ❌ No token expiration
  • ❌ Using weak secrets

  • ✅ Use HTTP-only cookies if possible

  • ✅ Always set expiresIn

  • ✅ Rotate secrets in production

🧠 When Should You Use JWT?

JWT is great when:

  • You have stateless APIs
  • You use microservices
  • You need mobile or SPA authentication

JWT is not ideal when:

  • You need instant logout everywhere
  • You need heavy session control

🏁 Conclusion

JWT provides a simple, scalable, and stateless way to handle authentication.
When used correctly, it’s powerful and secure.

If you’re building APIs, SPAs, or mobile apps — JWT is worth mastering.

Similar Posts