Implementing JWT authentication with Next.js Middleware for protected routes ensures your application’s security while streamlining developer workflows. By leveraging middleware for centralized authentication checks, you eliminate repetitive code and enhance protection across all routes.
Why Use Next.js Middleware for JWT Authentication?
Next.js Middleware executes before requests reach your pages or API routes, making it ideal for authentication logic. Unlike traditional server-side checks, middleware centralizes security rules, reducing code duplication and ensuring consistent enforcement across your entire application. This approach is especially valuable for protecting both API endpoints and client-side routes in a single layer.
Step-by-Step Implementation Guide for Next.js JWT Middleware
Here’s how to implement JWT authentication using Next.js Middleware for protected routes:
Setting Up JWT Tokens
First, install the jsonwebtoken package and configure your secret key in environment variables. Use Zod to validate these variables for security (see our guide on validating environment variables with Zod for best practices).
- Generate tokens with a short expiration (e.g., 15 minutes) for access tokens.
- Store refresh tokens in httpOnly cookies to prevent XSS attacks.
- Always sign tokens using strong algorithms like HS256.
Middleware for Route Protection
Create a middleware file in your app directory (e.g., middleware.ts) to validate tokens:
import { NextResponse } from 'next/server';
import jwt from 'jsonwebtoken';
export const config = {
matcher: ['/dashboard/:path*'],
};
export function middleware(req) {
const token = req.cookies.get('access_token')?.value;
if (!token) return NextResponse.redirect('/login');
try {
jwt.verify(token, process.env.JWT_SECRET);
return NextResponse.next();
} catch (err) {
return NextResponse.redirect('/login');
}
}
Handling Token Refresh
Implement a refresh token endpoint to issue new access tokens when they expire. This endpoint should:
- Validate the refresh token stored in an httpOnly cookie
- Issue a new access token with a short expiration
- Rotate the refresh token periodically to limit exposure
Client-Side Route Protection
For client-side routing, use a custom hook to check authentication status before rendering protected components:
export const useAuth = () => {
const [user, setUser] = useState(null);
useEffect(() => {
const token = localStorage.getItem('token');
if (token) {
// Verify token via API or decode client-side
setUser(jwt.decode(token));
}
}, []);
return user;
};
Security Best Practices
Maximize JWT security with these strategies:
- Always use HTTPS to prevent token interception
- Set
SameSite=Strictfor cookies to mitigate CSRF - Implement token revocation for compromised tokens
- Avoid storing sensitive data in JWT payloads
Conclusion
Implementing JWT authentication with Next.js Middleware for protected routes provides a robust, scalable solution for securing your application. By centralizing validation in middleware, using secure token storage, and following best practices, you can protect both API and client-side routes effectively. Start by validating your environment variables with Zod to ensure secret keys are properly configured, then implement the middleware steps outlined here for immediate security improvements.