How to Use Middleware in Next.js 14 for Route Protection
Implement middleware in Next.js 14 to protect routes, manage user authentication, handle role-based access. Middleware allows you to protect sensitive areas, such as user dashboards, while keeping public pages accessible to everyone.
In Next.js 14, middleware is essential for controlling access to different parts of your website. Middleware allows you to protect sensitive areas, such as user dashboards, while keeping public pages accessible to everyone. I'm going to walk you through an overview of setting up and using middleware for route protection in your Next.js 14 project.
Setting Up Middleware
- Create a Middleware File: Create a
middleware.ts
ormiddleware.js
file in your project's root directory. This file will contain the logic for checking user authentication and authorizing access to protected routes. - Authorize User Access: Inside the middleware file, you will include logic to check for authentication tokens and authorize user access. This ensures that only authenticated users can access protected routes.
Defining Protected Routes
Not all routes require authorization. Use the matcher
option in your middleware to specify routes that do and do not require authorization checks. This allows you to protect specific routes while keeping others publicly accessible.
Middleware Logic
The middleware logic will involve verifying if a user is authenticated by checking for a valid authentication token. You can also check user roles or permissions for more granular control over access to different routes.
Handling Unauthorized Access
If a user is not authenticated or does not have the necessary permissions, you can redirect them to a login or error page. This ensures that unauthorized users cannot access protected areas of your website.
Example Middleware File
Here's an example of how you can set up a middleware file in Next.js 14:
- Create the Middleware File: In your project's root directory, create
middleware.js
ormiddleware.ts
. - Write Middleware Logic: Use the
getToken
function fromnext-auth/jwt
to verify if a user is authenticated. If not, redirect them to the login page. If authenticated, allow them to proceed. - Define the Protected Routes: Use the
matcher
property to specify the routes that need protection. In the example below, the root (/
) and/sales
paths are protected. - Handle Unauthorized Access: Redirect users without a valid token to the login page.
Tip: Setting up process.env.NEXTAUTH_SECRET
When implementing authentication, you need to set the NEXTAUTH_SECRET
environment variable to securely handle JWT tokens. On Windows, you can use PowerShell to generate a random string. Here are five different PowerShell commands to generate a secure random string:
1. -join ((48..57) + (65..90) + (97..122) | Get-Random -Count 32 | % {[char]$_})
2. [Convert]::ToBase64String([Guid]::NewGuid().ToByteArray())
3. [guid]::NewGuid().ToString("N").Substring(0, 32)
4. -join (1..32 | ForEach-Object { [char](Get-Random -Minimum 33 -Maximum 126) })
5. openssl rand -base64 32 // on Mac
Example for Setting Up Middleware in Next.js 14
import { getToken } from 'next-auth/jwt';
import { NextResponse } from 'next/server';
export async function middleware(req) {
const token = await getToken({ req, secret: process.env.NEXTAUTH_SECRET });
if (!token) {
const signInUrl = new URL('/auth', req.url);
return NextResponse.redirect(signInUrl);
}
return NextResponse.next();
}
export const config = {
matcher: ['/', '/sales/:path*'], // protected routes
};
Protecting Specific Routes
To protect specific routes, use the matcher
configuration to define which routes are protected. For example:
export const config = {
matcher: ['/dashboard/:path*', '/transactions/:path*'], // specific protected routes
};
Conditional Navigation
After successful authentication, you can manage user navigation based on their roles. For instance, you might want to redirect an admin user to the admin dashboard and a regular user to their respective page.
Example for Role-Based Redirection
An example of middleware that handles role-based redirection:
export function middleware(request) {
const currentUser = request.cookies.get('currentUser')?.value;
if (currentUser && !request.nextUrl.pathname.startsWith('/dashboard')) {
return Response.redirect(new URL('/dashboard', request.url));
}
if (!currentUser && !request.nextUrl.pathname.startsWith('/login')) {
return Response.redirect(new URL('/login', request.url));
}
}
export const config = {
matcher: ['/((?!api|_next/static|_next/image|.*\\.png$).*)'],
};
Conclusion
Implementing middleware in Next.js 14 ensures secure access to protected routes and provides a seamless user experience by managing redirections and role-based access control.
Related Tags
Recommended
2m · 6min read
Web Development
2m · 6min read
Build a Real-time Speech Recognition Search Box with Next.js and Tailwind CSS
Building a real-time speech recognition search box using Next.js, Tailwind CSS, and the react-speech-recognition library
2m · 5min read
Web Development
2m · 5min read
How to Show Customized Relative Time with JavaScript
Learn how to create a JavaScript function to display relative time (like "5min ago" or "2y ago") by calculating the difference between the current date and an input date, converting it into various time units (seconds, minutes, hours, days, weeks, months, years), and returning the most appropriate unit as a string.
2m · 4min read
Web Development
2m · 4min read
How to Use Middleware in Next.js 14 for Route Protection
Implement middleware in Next.js 14 to protect routes, manage user authentication, handle role-based access. Middleware allows you to protect sensitive areas, such as user dashboards, while keeping public pages accessible to everyone.
2m · 5min read
Web Development
2m · 5min read
State Context vs Redux in React.js: When to Use Each One?
Learn the key differences between React's Context API and Redux for effective state management in your React.js applications, and discover which solution suits your project best.
2m · 4min read
Web Development
2m · 4min read
Build a Reusable Navbar Component for Multiple Pages Using HTML, CSS, and JavaScript
In this tutorial, we learned how to create a reusable navbar component using HTML, CSS, and JavaScript by dynamically loading the navbar into multiple pages, ensuring consistency and simplifying maintenance across the website.
3m · 4min read
Web Development
3m · 4min read
How to Integrate Dark Mode and Light Mode Toggle in Next.js with Tailwind CSS
Implement dynamic dark mode and light mode in Next.js with Tailwind CSS to improve user experience, accessibility, and visual customization.
4m · 6min read
Web Development
4m · 6min read
Cross-Origin Resource Sharing (CORS): How To Fix CORS
Cross-Origin Resource Sharing (CORS) is a browser mechanism that enables controlled access to resources from different domains, extending the same-origin policy while providing potential for cross-domain attacks if improperly configured.
4m · 5min read
Web Development
4m · 5min read
TypeScript Types vs Interfaces
Types vs Interfaces: Types in TypeScript are more flexible and can define a wider range of data types, including primitives, unions, intersections, tuples, and more, while interfaces are primarily used to describe the shape of objects and support declaration merging and extending, making them ideal for object-oriented programming and complex data structures
5m · 3min read
Web Development
5m · 3min read
The this Keyword in JavaScript
The this keyword in JavaScript is a reference to the object that a function is a property of. It's a fundamental concept in JavaScript, especially in object-oriented programming. Unlike in languages like Java, C#, or PHP, where this typically refers to the current instance of the class, JavaScript's this behaves differently and can be quite versatile.
6m · 8min read
Web Development
6m · 8min read
30 Common CSS Mistakes
30 CSS common mistakes we make includes: complicating selectors,Overuse of the “!important” declaration, Mishandling the z-index property, Duplicating code, Relying solely on color names and more