DEV Community

Cover image for Validate user path access on edge with NextAuth & Next.js Middleware
Syed Muhammad Yaseen
Syed Muhammad Yaseen

Posted on

Validate user path access on edge with NextAuth & Next.js Middleware

....

Cover Photo by Susan Q Yin on Unsplash

Source Code: https://gist.github.com/smyaseen/eb1ad52e85b7a6665642430bc4b9da31

....

Helloooooo!

Hope you're doing great! This is SMY! 👋 Let's Jump right in 🚀

Contents:

  • Some Background of NextAuth and Middleware

  • Implementation of NextAuth and Middleware validating user path access on edge

1️⃣ What -

  • NextAuth.js: NextAuth.js is an open-source authentication library specifically designed for Next.js applications. It supports various authentication providers such as Google, Facebook, and custom providers, offering a comprehensive solution for user authentication.

  • NextJS Middleware: NextJS Middleware allows you to intercept and modify requests before your Next.js application handles them. This capability is essential for tasks like authentication, where you may need to redirect users, check authorization, or modify headers dynamically.

2️⃣ Why -

  • Flexibility: NextAuth.js supports multiple authentication providers and allows for customization to fit diverse application needs.

  • Edge Validation: NextJS Middleware enables validation and customization of requests at the edge, similar to an API gateway, ensuring robust security and tailored user experiences.

  • Streamlined Authorization: By combining NextAuth.js and NextJS Middleware, you can efficiently manage user authorization and control page access without complex conditional rendering.

3️⃣ How -

Step 1: Install Dependencies

First, ensure you have NextAuth.js installed in your Next.js project. Head over to NextAuth's documentation to learn more about integration:

https://next-auth.js.org/getting-started/introduction

Step 2: Configure NextAuth.js

Set up NextAuth.js with your preferred authentication providers and configuration options. Below is a basic example using JWT strategy:

// pages/api/auth/[...nextauth].ts

import NextAuth from 'next-auth';
import Providers from 'next-auth/providers';

export default NextAuth({
  pages: {
    signIn: '/login',
  },
  providers: [
    Providers.JWT({
      secret: process.env.JWT_SECRET,
      // Additional JWT options if needed
    }),
    // Add other providers like Google, Facebook, etc.
  ],
  // Optional NextAuth.js configurations
});
Enter fullscreen mode Exit fullscreen mode

Step 3: Implement NextJS Middleware

Create a middleware function to handle authentication and authorization logic:

// middleware.ts

import { NextFetchEvent, NextRequest, NextResponse } from 'next/server';
import { getToken } from 'next-auth/jwt';
import { withAuth } from 'next-auth/middleware';

/*
 * Match all request paths except for the ones starting with:
 * - api (API routes)
 * - _next/static (static files)
 * - _next/image (image optimization files)
 * - favicon.ico (favicon file)
 */
const pathsToExclude = /^(?!\/(api|_next\/static|favicon\.ico|manifest|icon|static)).*$/;

// set of public pages that needed to be excluded from middleware
const publicPagesSet = new Set<string>(['home']);

const rootRegex = /^\/($|\?.+|#.+)?$/;

export default async function middleware(req: NextRequest, event: NextFetchEvent) {
  if (!pathsToExclude.test(req.nextUrl.pathname) || publicPagesSet.has(req.nextUrl.pathname))
    return NextResponse.next();

  const token = await getToken({ req });
  const isAuthenticated = !!token;

  // if user goes to root path '/' then redirect
  // /dashboard if authenticated
  // /login if unauthenticated
  if (rootRegex.test(req.nextUrl.pathname)) {
    if (isAuthenticated) return NextResponse.redirect(new URL('/dashboard', req.url)) as NextResponse;
    return NextResponse.redirect(new URL('/login', req.url)) as NextResponse;
  }

  // redirects user from '/login' if authenticated
  if (req.nextUrl.pathname.startsWith('/login') && isAuthenticated) {
    return NextResponse.redirect(new URL('/dashboard', req.url)) as NextResponse;
  }

  // This has to be same page option as in AuthOptions
  const authMiddleware = await withAuth({
    pages: {
      signIn: `/login`,
    },
  });

  return authMiddleware(req, event);
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Understand the Middleware Logic

  • Paths to Exclude: pathsToExclude regex ensures that certain paths like API routes (/api/*), static files (/_next/static/*), and others are excluded from middleware processing.

  • Public Pages Set: publicPagesSet contains paths that are considered public and shouldn't be protected by middleware.

  • JWT Token: getToken({ req }) retrieves the JWT token from the request headers or cookies.

  • Authentication Checks: The middleware checks if the user is authenticated (isAuthenticated). If not, it redirects to the login page (/login). If authenticated and accessing the root path (/), it redirects to /dashboard.

  • NextAuth Middleware: For other protected routes, it utilizes withAuth from next-auth/middleware to enforce authentication requirements.

Wrapping Up:

Implementing NextJS Middleware involves creating a middleware function (middleware.ts) that intercepts requests, performs authentication checks, and handles redirection based on the user's authentication status. This approach ensures secure and streamlined authentication within your Next.js application, enhancing both security and user experience.

By following these steps, you can effectively integrate NextAuth.js with NextJS Middleware to manage authentication and authorization in your Next.js projects. Adjust the middleware logic and configuration based on your specific application requirements and security policies.

.....

Now you're equipped to enhance your Next.js applications with robust authentication capabilities using NextAuth.js and NextJS Middleware. Happy coding! 🚀

That's it, folks! hope it was a good read for you. Thank you! ✨

👉 Follow me

GitHub

LinkedIn

Top comments (0)