Introduction to JWT authentication in Next.js full setup

If you're building secure web applications, understanding JWT authentication in Next.js full setup is essential. JWT (JSON Web Token) allows you to securely transmit user data between the client and server, making authentication fast and scalable.

Unlike traditional session-based authentication, JWT is stateless, which means your server doesn’t need to store session data. This makes it perfect for modern applications built with Next.js.

In this guide, you'll learn how to implement JWT authentication step by step.

What is JWT Authentication?

JWT authentication uses a token-based system where a signed token is issued after a user logs in successfully.

A JWT consists of three parts:

  • Header

  • Payload

  • Signature

This token is then sent with each request to verify the user's identity.

Why Use JWT in Next.js Applications

JWT is popular because:

  • It’s stateless and scalable

  • Works well with APIs

  • Reduces server load

  • Easy to implement in modern frameworks

Prerequisites for JWT Setup

Before starting this JWT authentication in Next.js full setup, ensure you have the right tools.

Required Tools and Environment

You’ll need:

  • Node.js installed

  • A Next.js project

  • Basic JavaScript knowledge

Creating a Next.js Project

npx create-next-app@latest jwt-app
cd jwt-app

Installing Required Dependencies

jsonwebtoken Package

Install JWT library:

npm install jsonwebtoken

bcrypt for Password Hashing

npm install bcryptjs

Step-by-Step JWT authentication in Next.js full setup

Now let’s build the authentication system step by step.

Creating User Model

Example user structure:

const user = {
  email: "user@example.com",
  password: "hashed_password",
};

Building API Route for Login

Create file:

/pages/api/login.js

Example:

import jwt from "jsonwebtoken";

export default function handler(req, res) {
  const { email, password } = req.body;

  // Validate user (dummy example)
  if (email === "user@example.com" && password === "123456") {
    const token = jwt.sign({ email }, process.env.JWT_SECRET, {
      expiresIn: "1h",
    });

    res.status(200).json({ token });
  } else {
    res.status(401).json({ message: "Invalid credentials" });
  }
}

Generating JWT Token

The jwt.sign() method creates a token using:

  • Payload (user data)

  • Secret key

  • Expiration time

Storing Token in Cookies

Use HTTP-only cookies for security:

res.setHeader(
  "Set-Cookie",
  `token=${token}; HttpOnly; Path=/; Max-Age=3600`
);

Verifying JWT Token

Middleware for Protected Routes

Create middleware:

import jwt from "jsonwebtoken";

export function verifyToken(req) {
  const token = req.headers.authorization;

  if (!token) return null;

  try {
    return jwt.verify(token, process.env.JWT_SECRET);
  } catch {
    return null;
  }
}

Decoding and Validating Tokens

Use:

jwt.verify(token, secret);

This ensures:

  • Token is valid

  • Not expired

Protecting Pages and API Routes

Client-Side Route Protection

Check authentication before rendering:

if (!token) {
  router.push("/login");
}

Server-Side Protection

Use getServerSideProps:

export async function getServerSideProps(context) {
  const token = context.req.cookies.token;

  if (!token) {
    return { redirect: { destination: "/login" } };
  }

  return { props: {} };
}

Handling Authentication State

Managing User Sessions

Store user data in:

  • Cookies

  • Context API

Logout Functionality

Clear cookie:

res.setHeader("Set-Cookie", "token=; Max-Age=0; Path=/");

Error Handling in JWT Authentication

Expired Tokens

Return appropriate response:

  • 401 Unauthorized

Invalid Tokens

Always validate tokens before granting access.

Security Best Practices

Using HTTP-Only Cookies

Prevents JavaScript access to tokens, reducing XSS risks.

Avoiding Token Exposure

Never store tokens in localStorage for sensitive apps.

Token Expiry Strategy

Use short-lived tokens with refresh tokens.

Advanced JWT Techniques

Refresh Tokens

Use refresh tokens to:

  • Extend sessions

  • Improve security

Role-Based Authentication

Add roles in JWT payload:

jwt.sign({ email, role: "admin" }, secret);

FAQs About JWT authentication in Next.js full setup

1. What is JWT used for?

JWT is used for secure authentication and data exchange.

2. Is JWT better than sessions?

JWT is more scalable but depends on use case.

3. Can JWT expire?

Yes, tokens have expiration times.

4. Is JWT secure?

Yes, when implemented correctly with best practices.

5. Where should I store JWT?

Prefer HTTP-only cookies.

6. Can I use JWT with NextAuth?

Yes, NextAuth supports JWT-based sessions.

Conclusion

This JWT authentication in Next.js full setup guide gives you everything you need to build a secure authentication system from scratch. From token generation to route protection, you now have a solid foundation.

By following best practices and implementing advanced techniques like refresh tokens, you can ensure your application remains secure, scalable, and efficient.