codingstuff.io
ExploreTutorialsProblemsCS Subjects
Get Started
ExploreTutorialsProblemsCS Subjects
Get Started
codingstuff.io

Master the art of building software through interactive tutorials, real-world problems, and guided projects.

Pune, Maharashtra, India

codingstuffmail@gmail.com

Product

  • Explore
  • Tutorials
  • Problems
  • CS Subjects

Company

  • About
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Sitemap

© 2026 codingstuff.io. All rights reserved.

Built with ❤️ for developers everywhere

/
/
All Tutorials
▲

Next.js

33 / 73 topics
32Authentication and Authorization33JWT Authentication34OAuth Integration35Session Management36Protecting Routes
Tutorials/Next.js/JWT Authentication
▲Next.js

JWT Authentication

Updated 2026-04-20
2 min read

JWT Authentication

In this section, we will explore how to implement JSON Web Token (JWT) authentication in a Next.js application. JWT is a compact, URL-safe means of representing claims to be transferred between two parties. It allows you to authenticate users and protect routes in your application.

Understanding JWT

Before diving into implementation, let's understand the basics of JWT:

  • Header: Contains metadata about the token, such as the type (JWT) and the signing algorithm used.
  • Payload: Contains claims. Claims are statements about an entity (typically, the user) and additional data.
  • Signature: Ensures that the message wasn't changed along the way and verifies that the sender is who it says it is.

Setting Up Next.js

First, ensure you have a Next.js project set up. If not, create one using:

npx create-next-app@latest my-nextjs-app
cd my-nextjs-app

Installing Required Packages

We will use jsonwebtoken for signing and verifying tokens, and express-session to manage sessions.

npm install jsonwebtoken express-session

Creating a JWT Utility

Create a utility file to handle JWT operations. This will include generating and verifying tokens.

// utils/jwt.js
import jwt from 'jsonwebtoken';

const secretKey = process.env.JWT_SECRET || 'your_secret_key'; // Use environment variables for security

export const generateToken = (payload) => {
  return jwt.sign(payload, secretKey, { expiresIn: '1h' }); // Token expires in 1 hour
};

export const verifyToken = (token) => {
  try {
    return jwt.verify(token, secretKey);
  } catch (error) {
    throw new Error('Invalid token');
  }
};

Implementing Middleware for Authentication

Create a middleware to protect routes that require authentication.

// middleware/auth.js
import { verifyToken } from '../utils/jwt';

export default function authMiddleware(handler) {
  return async (req, res) => {
    const token = req.headers.authorization?.split(' ')[1];

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

    try {
      const decoded = verifyToken(token);
      req.user = decoded;
      return handler(req, res);
    } catch (error) {
      return res.status(403).json({ message: error.message });
    }
  };
}

Protecting Routes

Use the middleware to protect routes. For example, let's protect a profile route.

// pages/api/profile.js
import authMiddleware from '../../middleware/auth';

export default authMiddleware((req, res) => {
  if (req.method === 'GET') {
    return res.status(200).json({ message: 'Profile accessed', user: req.user });
  }
});

User Authentication

Implement a login endpoint to authenticate users and issue JWTs.

// pages/api/login.js
import { generateToken } from '../../utils/jwt';

export default async function handler(req, res) {
  if (req.method === 'POST') {
    const { username, password } = req.body;

    // Normally you would validate credentials against a database
    if (username === 'admin' && password === 'password') {
      const token = generateToken({ username });
      return res.status(200).json({ message: 'Login successful', token });
    }

    return res.status(401).json({ message: 'Invalid credentials' });
  }
}

Client-Side Handling

On the client side, you can use the token to make authenticated requests. Here's an example using fetch.

// pages/index.js
import { useState } from 'react';

export default function Home() {
  const [token, setToken] = useState('');

  const login = async () => {
    const response = await fetch('/api/login', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ username: 'admin', password: 'password' }),
    });

    if (response.ok) {
      const data = await response.json();
      setToken(data.token);
    } else {
      console.error('Login failed');
    }
  };

  const fetchProfile = async () => {
    const response = await fetch('/api/profile', {
      headers: { Authorization: `Bearer ${token}` },
    });

    if (response.ok) {
      const data = await response.json();
      console.log(data);
    } else {
      console.error('Failed to fetch profile');
    }
  };

  return (
    <div>
      <button onClick={login}>Login</button>
      {token && <button onClick={fetchProfile}>Fetch Profile</button>}
    </div>
  );
}

Best Practices

  1. Secure Your Secret Key: Never hardcode your JWT secret key in the codebase. Use environment variables.
  2. HTTPS: Always use HTTPS to protect tokens from being intercepted during transmission.
  3. Token Expiry: Set an appropriate expiry time for tokens and implement refresh tokens for long-lived sessions.
  4. Input Validation: Validate all inputs on both client and server sides to prevent injection attacks.

Conclusion

JWT authentication is a robust method for securing your Next.js application. By following the steps outlined in this tutorial, you can implement JWT-based authentication, protect routes, and manage user sessions effectively. Remember to adhere to best practices to ensure the security of your application.


PreviousAuthentication and AuthorizationNext OAuth Integration

Recommended Gear

Authentication and AuthorizationOAuth Integration