Introduction
Managing access control, redirects, and pre-request logic is crucial for complex applications. Next.js provides Middleware to run code before requests, enabling global logic for tasks like authentication and authorization. This lesson covers implementing Next.js Middleware and discusses common strategies for securing your application using popular authentication solutions, ensuring controlled access to resources.
Key Concepts
Next.js Middleware
-
Function: Middleware allows you to run code before a request is completed. It can modify the incoming request, rewrite, redirect, or respond directly.
-
Location: Defined in a
middleware.js(or.ts) file at the root of your project (or withinsrc/). -
Execution: Runs on the server-side, for every route matching its configuration.
-
Use Cases:
-
Authentication: Check if a user is logged in and redirect if not.
-
Authorization: Verify user roles or permissions.
-
A/B Testing: Rewrite requests to different versions of pages.
-
Bot Detection: Block malicious requests.
-
Internationalization: Rewrite URLs based on locale.
Basic Middleware Structure: javascript // middleware.js import { NextResponse } from 'next/server';
export function middleware(request) { // Example: Redirect to /login if user is not authenticated const isLoggedIn = request.cookies.get('token'); // Check for a token cookie if (!isLoggedIn && request.nextUrl.pathname.startsWith('/dashboard')) { return NextResponse.redirect(new URL('/login', request.url)); } return NextResponse.next(); // Continue to the requested page }
// Optional: Configure which paths the middleware applies to export const config = { matcher: ['/dashboard/:path*', '/api/:path*'], };
Authentication in Next.js
Authentication is verifying who a user is.
Common methods include:
-
NextAuth.js: A popular, flexible open-source solution for Next.js authentication. Supports various providers (Google, GitHub, email/password) and JWT/database sessions.
-
Manual JWT/Session Management: Implement your own authentication logic using API routes for login/logout and managing JWTs or session tokens in cookies.
-
Third-party BaaS (Backend-as-a-Service): Solutions like Firebase Auth, Supabase Auth, or Auth0 integrate seamlessly with Next.js.
Authorization in Next.js
Authorization determines what an authenticated user is allowed to do.
-
Middleware: Can be used to check user roles or permissions from the
requestobject. -
API Routes: Protect sensitive API endpoints by verifying the user's token and permissions server-side.
-
Component-level: Conditionally render UI elements based on user roles (ensure this is also backed by server-side checks).
-
Session Storage: Store user roles or permissions in secure server-side sessions or encrypted JWTs.
Code Example: Authentication Check with NextAuth.js (Conceptual)
While a full NextAuth.js setup is extensive, here's a conceptual look at how it integrates.
jsx // pages/dashboard.js (Protected Page) import { useSession, getSession } from 'next-auth/react'; import Layout from '../components/Layout';
export default function Dashboard() { const { data: session, status } = useSession();
if (status === 'loading') { return <Layout><p>Loading...</p></Layout>; }
if (status === 'unauthenticated') { return <Layout><p>Access Denied. Please log in.</p></Layout>; }
return ( <Layout> <h1>Welcome, {session.user.name}</h1> <p>This is your protected dashboard content.</p> </Layout> ); }
// Optional: Server-side check for authentication export async function getServerSideProps(context) { const session = await getSession(context); // Get session from server if (!session) { return { redirect: { destination: '/api/auth/signin', // Redirect to login page permanent: false, }, }; } return { props: { session }, }; }
Key Takeaways
-
Next.js Middleware allows executing code before a request, useful for global logic like authentication/authorization checks.
-
Middleware is defined in
middleware.jsand can rewrite, redirect, or respond to requests. -
NextAuth.js is a recommended solution for robust authentication in Next.js.
-
Authorization involves checking user roles/permissions, often done in Middleware, API Routes, or server-side data fetching functions.
-
Combine client-side
useSessionwith server-sidegetSession(orgetServerSidePropschecks) for comprehensive protection.