Next.js Discord

Discord Forum

Next-Auth and Middleware - How to protect pages.

Unanswered
Hamodi posted this in #help-forum
Open in Discord
I am having trouble securing specific pages in my Next.js application after authentication using Middleware and NextAuth.

Pages are protected until a user logs in, at which point they become visible. However, after logging in, I don't want to show the /dashboard page to users with the "USER" role or the /booking page to users with the "ADMIN" role. Additionally, I don't want to display the homepage (/) or the /signup page post-login.

Here's the code I've used:

import { withAuth } from 'next-auth/middleware';

export default withAuth({
  callbacks: {
    authorized: (params) => {
      let { token } = params;
      return !!token;
    },
  },
});

export const config = {
  matcher: ["/dashboard/:path*", "/booking/:path*", "/settings/:path*"]
};

I tried to use the middleware function with if statements like:
import { NextResponse } from 'next/server';
import { withAuth } from 'next-auth/middleware';

export default withAuth(
    function middleware(req) {
      if (req.nextUrl.pathname.startsWith("/") && req.nextauth.token?.role === "USER") {
        const url = req.nextUrl.clone();
        url.pathname = "/booking";
        return NextResponse.redirect(url);
      }
  
      if (req.nextUrl.pathname.startsWith("/") && req.nextauth.token?.role === "ADMIN") {
        const url = req.nextUrl.clone();
        url.pathname = "/dashboard";
        return NextResponse.redirect(url);
      }
  
      if (req.nextUrl.pathname.startsWith("/signup") && req.nextauth.token?.role === "USER") {
        const url = req.nextUrl.clone();
        url.pathname = "/booking";
        return NextResponse.redirect(url);
      }
  
      if (req.nextUrl.pathname.startsWith("/signup") && req.nextauth.token?.role === "ADMIN") {
        const url = req.nextUrl.clone();
        url.pathname = "/dashboard";
        return NextResponse.redirect(url);
      }


      if (req.nextUrl.pathname.startsWith("/dashboard") && req.nextauth.token?.role === "USER") {
        const url = req.nextUrl.clone();
        url.pathname = "/booking";
        return NextResponse.redirect(url);
      }
  
      if (req.nextUrl.pathname.startsWith("/booking") && req.nextauth.token?.role === "ADMIN") {
        const url = req.nextUrl.clone();
        url.pathname = "/dashboard";
        return NextResponse.redirect(url);
      }
  
    },
  
    {
      callbacks: {
        authorized: (params) => {
          let { token } = params;
          return !!token;
        },
      },
    }
  );
  
  export const config = {
    matcher: ["/dashboard/:path*", "/booking/:path*", "/settings/:path*"]
  };

According to the documentation: "The middleware function will only be invoked if the authorized callback returns true."

Code from the documentation:
import { withAuth } from "next-auth/middleware"

export default withAuth(
  // `withAuth` augments your `Request` with the user's token.
  function middleware(req) {
    console.log(req.nextauth.token)
  },
  {
    callbacks: {
      authorized: ({ token }) => token?.role === "admin",
    },
  }
)

export const config = { matcher: ["/admin"] }
However, it doesn't seem to work as expected. Can anyone guide me on how to correctly secure specific routes using middleware and NextAuth?

0 Replies