Next.js Discord

Discord Forum

Middleware issues when in production on Render.com

Unanswered
Cuban Crocodile posted this in #help-forum
Open in Discord
Cuban CrocodileOP
Hi, my application is in production on render.com and I want my middleware to work properly. Essentially, my code should not let users book a ticket unless they are logged in and have a Customer role. My middleware works properly on the localhost when running npm run dev but it does not work in a production enviornment.

I have followed the fixes I saw on GitHub like enabling strategy: jwt, setting AUTH_URL to DOMAIN/api/auth and some other changes that were recommended in the middleware file and also including it to the tsconfig.json file. Here is my code:

middleware.ts
import { withAuth } from "next-auth/middleware";
import { NextResponse } from "next/server";

export default withAuth(
    function middleware(req) {
        if (req.nextUrl.pathname.startsWith("/admin") && req.nextauth.token?.role !== "M") {
            const redirectUrl = `${req.nextUrl.origin}/not-found?message=${encodeURIComponent("Admin access only.")}`;
            return NextResponse.redirect(redirectUrl);
        }
        if (req.nextUrl.pathname.startsWith("/employee") && req.nextauth.token?.role !== "E") {
            const redirectUrl = `${req.nextUrl.origin}/not-found?message=${encodeURIComponent("Employee access only.")}`;
            return NextResponse.redirect(redirectUrl);
        }
        if (req.nextUrl.pathname.startsWith("/booking") && req.nextauth.token?.role !== "C") {
            console.log(req.nextauth.token?.role)
            const redirectUrl = `${req.nextUrl.origin}/not-found?message=${encodeURIComponent("Customer access only.")}`;
            return NextResponse.redirect(redirectUrl);
        }

        if (req.nextUrl.pathname.startsWith("/support") && req.nextauth.token?.role !== "C" && req.nextauth.token?.role !== "S") {
            const redirectUrl = `${req.nextUrl.origin}/not-found?message=${encodeURIComponent("Customer and Support access only.")}`;
            return NextResponse.redirect(redirectUrl);
        }
    },
    {
        callbacks: {
            authorized: (params) => {
                let { token } = params;
                return !!token;
            },
        },
    }
);

export const config = { matcher: ['/admin/:path*', '/employee/:path*', '/booking/:path*', '/support/:path*'] };


next-auth options:
export const options: NextAuthOptions = {
    session: {
        strategy: 'jwt',
        maxAge: 30 * 24 * 60 * 60,
    },
    adapter: PrismaAdapter(prisma),
    providers: [
        ...
    ],
    pages: {
        signIn: '/auth/signin',
    },
    secret: process.env.NEXTAUTH_SECRET,
    useSecureCookies: false,
    callbacks: {
        async session({ session, token }) {
            if (session.user) {...
            }
            return session;
        },
        async jwt({ token, user }) {
            if (user) {...
            }
            return token;
        },
    }
}


Additionally, I have also set prefetch to false fo when trying to go the booking page but no results there either.

Here is my domain: https://exhibit-ease-dev.onrender.com/

You can log in with the following credentials if you would like to test it:
email: test@a.com
password: 123

2 Replies

@Cuban Crocodile Hi, my application is in production on render.com and I want my middleware to work properly. Essentially, my code should not let users book a ticket unless they are logged in and have a Customer role. My middleware works properly on the localhost when running `npm run dev` but it does not work in a production enviornment. I have followed the fixes I saw on GitHub like enabling `strategy: jwt`, setting `AUTH_URL` to `DOMAIN/api/auth` and some other changes that were recommended in the middleware file and also including it to the `tsconfig.json` file. Here is my code: middleware.ts typescript import { withAuth } from "next-auth/middleware"; import { NextResponse } from "next/server"; export default withAuth( function middleware(req) { if (req.nextUrl.pathname.startsWith("/admin") && req.nextauth.token?.role !== "M") { const redirectUrl = `${req.nextUrl.origin}/not-found?message=${encodeURIComponent("Admin access only.")}`; return NextResponse.redirect(redirectUrl); } if (req.nextUrl.pathname.startsWith("/employee") && req.nextauth.token?.role !== "E") { const redirectUrl = `${req.nextUrl.origin}/not-found?message=${encodeURIComponent("Employee access only.")}`; return NextResponse.redirect(redirectUrl); } if (req.nextUrl.pathname.startsWith("/booking") && req.nextauth.token?.role !== "C") { console.log(req.nextauth.token?.role) const redirectUrl = `${req.nextUrl.origin}/not-found?message=${encodeURIComponent("Customer access only.")}`; return NextResponse.redirect(redirectUrl); } if (req.nextUrl.pathname.startsWith("/support") && req.nextauth.token?.role !== "C" && req.nextauth.token?.role !== "S") { const redirectUrl = `${req.nextUrl.origin}/not-found?message=${encodeURIComponent("Customer and Support access only.")}`; return NextResponse.redirect(redirectUrl); } }, { callbacks: { authorized: (params) => { let { token } = params; return !!token; }, }, } ); export const config = { matcher: ['/admin/:path*', '/employee/:path*', '/booking/:path*', '/support/:path*'] }; next-auth options: typescript export const options: NextAuthOptions = { session: { strategy: 'jwt', maxAge: 30 * 24 * 60 * 60, }, adapter: PrismaAdapter(prisma), providers: [ ... ], pages: { signIn: '/auth/signin', }, secret: process.env.NEXTAUTH_SECRET, useSecureCookies: false, callbacks: { async session({ session, token }) { if (session.user) {... } return session; }, async jwt({ token, user }) { if (user) {... } return token; }, } } Additionally, I have also set `prefetch` to false fo when trying to go the booking page but no results there either. Here is my domain: https://exhibit-ease-dev.onrender.com/ You can log in with the following credentials if you would like to test it: email: test@a.com password: 123
Dwarf Crocodile
Did u find a solution? im facing the same problem
@Cuban Crocodile Hi, my application is in production on render.com and I want my middleware to work properly. Essentially, my code should not let users book a ticket unless they are logged in and have a Customer role. My middleware works properly on the localhost when running `npm run dev` but it does not work in a production enviornment. I have followed the fixes I saw on GitHub like enabling `strategy: jwt`, setting `AUTH_URL` to `DOMAIN/api/auth` and some other changes that were recommended in the middleware file and also including it to the `tsconfig.json` file. Here is my code: middleware.ts typescript import { withAuth } from "next-auth/middleware"; import { NextResponse } from "next/server"; export default withAuth( function middleware(req) { if (req.nextUrl.pathname.startsWith("/admin") && req.nextauth.token?.role !== "M") { const redirectUrl = `${req.nextUrl.origin}/not-found?message=${encodeURIComponent("Admin access only.")}`; return NextResponse.redirect(redirectUrl); } if (req.nextUrl.pathname.startsWith("/employee") && req.nextauth.token?.role !== "E") { const redirectUrl = `${req.nextUrl.origin}/not-found?message=${encodeURIComponent("Employee access only.")}`; return NextResponse.redirect(redirectUrl); } if (req.nextUrl.pathname.startsWith("/booking") && req.nextauth.token?.role !== "C") { console.log(req.nextauth.token?.role) const redirectUrl = `${req.nextUrl.origin}/not-found?message=${encodeURIComponent("Customer access only.")}`; return NextResponse.redirect(redirectUrl); } if (req.nextUrl.pathname.startsWith("/support") && req.nextauth.token?.role !== "C" && req.nextauth.token?.role !== "S") { const redirectUrl = `${req.nextUrl.origin}/not-found?message=${encodeURIComponent("Customer and Support access only.")}`; return NextResponse.redirect(redirectUrl); } }, { callbacks: { authorized: (params) => { let { token } = params; return !!token; }, }, } ); export const config = { matcher: ['/admin/:path*', '/employee/:path*', '/booking/:path*', '/support/:path*'] }; next-auth options: typescript export const options: NextAuthOptions = { session: { strategy: 'jwt', maxAge: 30 * 24 * 60 * 60, }, adapter: PrismaAdapter(prisma), providers: [ ... ], pages: { signIn: '/auth/signin', }, secret: process.env.NEXTAUTH_SECRET, useSecureCookies: false, callbacks: { async session({ session, token }) { if (session.user) {... } return session; }, async jwt({ token, user }) { if (user) {... } return token; }, } } Additionally, I have also set `prefetch` to false fo when trying to go the booking page but no results there either. Here is my domain: https://exhibit-ease-dev.onrender.com/ You can log in with the following credentials if you would like to test it: email: test@a.com password: 123
Hey, can you try running the following in the local system:
npm run build
npm run start


and then check if the middleware works?