NextJS middleware

Hello, In the middleware file, I want to check if the user is authenticated and allowed to visit specific pages. Currently how I do it is as following:
// Some page
const Page = () => { ... }

Page.auth = {
route: "/page"
protectFromNonAuth: {
roles: ["ADMIN"]
}
}

// NextJS Middleware file
const routes = [
{
route: "/page"
protectFromNonAuth: {
roles: ["ADMIN"]
}
}
]

export const middleware = async (req: NextRequest) => {
// Get the current route and find it in the routes array and check if user has
// permission to visit the page.
}
// Some page
const Page = () => { ... }

Page.auth = {
route: "/page"
protectFromNonAuth: {
roles: ["ADMIN"]
}
}

// NextJS Middleware file
const routes = [
{
route: "/page"
protectFromNonAuth: {
roles: ["ADMIN"]
}
}
]

export const middleware = async (req: NextRequest) => {
// Get the current route and find it in the routes array and check if user has
// permission to visit the page.
}
This works but what I don't like about it is that I now have double code for the same thing. When I import the auth functionality from all the pages, so like
const routes = [
Page.auth,
OtherPage.auth
];
const routes = [
Page.auth,
OtherPage.auth
];
it works in dev mode but when building for production, it says Dynamic Code Evaluation (e. g. 'eval', 'new Function', 'WebAssembly.compile') not allowed in Edge Runtime because I import those auth from the pages. Does someone know a better and cleaner way of doing this? I have quite some pages and I don't want to forgot also adding the auth in the routes array in the middleware.
2 Replies
Gaurang
Gaurang2y ago
Oddly i just shared this in another post earlier... this is how I'm currently handling this in my applications:
import { getToken } from "next-auth/jwt";
import { NextResponse } from "next/server";

import type { NextRequest } from "next/server";

export async function middleware(req: NextRequest) {
//token will exist if user is logged in
const token = await getToken({ req, secret: process.env.NEXTAUTH_SECRET });

const { pathname } = req.nextUrl;

const whitelist: string[] = ["api/auth", "/"];

if (whitelist.includes(pathname) || token) {
return NextResponse.next();
}

//redirect them to login if they don't have token and are
//requesting a protected route
const protectedRoutes: string[] = ["/admin"];

const isProtectedRoute = protectedRoutes.every((path) => path === pathname);

if (!token && isProtectedRoute) {
return NextResponse.redirect(new URL("/auth/signin", req.url));
}
});
}

export const config = {
matcher: "/",
};
import { getToken } from "next-auth/jwt";
import { NextResponse } from "next/server";

import type { NextRequest } from "next/server";

export async function middleware(req: NextRequest) {
//token will exist if user is logged in
const token = await getToken({ req, secret: process.env.NEXTAUTH_SECRET });

const { pathname } = req.nextUrl;

const whitelist: string[] = ["api/auth", "/"];

if (whitelist.includes(pathname) || token) {
return NextResponse.next();
}

//redirect them to login if they don't have token and are
//requesting a protected route
const protectedRoutes: string[] = ["/admin"];

const isProtectedRoute = protectedRoutes.every((path) => path === pathname);

if (!token && isProtectedRoute) {
return NextResponse.redirect(new URL("/auth/signin", req.url));
}
});
}

export const config = {
matcher: "/",
};
You can just as easily use getSession to get the current session if you're including your user roles on the session object.
EQ
EQ2y ago
Unfortunately, I don't use NextAuth since I have an external backend for some reasons
Want results from more Discord servers?
Add your server