Next.js Discord

Discord Forum

Middleware is triggering multiple times per redirect. What is the correct matcher?

Unanswered
European pilchard posted this in #help-forum
Open in Discord
European pilchardOP
I have a login page and a home page that is only accessible when the user logs in. The login form has a server action that stores a jwt in cookies. I would like to verify the lifetime/expiration of this jwt in the middleware on the page load/reload and any attempted server actions (home page has a form to submit sms emails which is a server action). If the jwt is expired, I would like to redirect to /auth, otherwise allow whatever action.

As of now, I have the middleware to return a NextResponse.redirect(new URL("/auth", request.url)) from my middleware, and the matcher I am using is:

matcher: ["/((?!api|static|_next|.*\\..*|favicon.ico).*)"]

I think this should work for the most part. However, the issue I am running into is the middleware infinitely redirecting when the jwt is expired. When I comment out the redirect, it looks like there are at least 2 middleware triggers happening per page load, sometimes more....

What matcher pattern can I use to only trigger middleware on select server actions and page load/reload?

2 Replies

European pilchardOP
middleware.ts
"use server";

import { NextRequest, NextResponse } from "next/server";
export async function middleware(request: NextRequest) {
/*
TODO: 
   1) update cookies with renewed JWT if still valid
   2) redirect to login if jwt is expired
   3) update context provider? 

   Figure out why middleware is calling multiple times 
   for the same route

*/

const cookie = request.cookies.get("bff-auth-session");

const jwt = require("jsonwebtoken");

try {
   const verify = jwt.decode(cookie!.value, { complete: true });
   // console.log("verify? ", verify);

   const currTime = Math.floor(Date.now() / 1000);

   if (verify.payload.exp < currTime) {
     if (1 < currTime) {
       // JWT Expired
       console.log("jwt expired");
       return NextResponse.redirect(new URL("/auth", request.url));
     } else {
       // JWT still valid
       console.log("jwt valid");
     }
   }
} catch (err) {
   console.error("Error verifying JWT token: ", err);
}

return NextResponse.next();
}

export const config = {
  // all paths except api and static content requests
  matcher: ["/((?!api|static|_next|.*\\..*|favicon.ico).*)"],
};
European pilchardOP
Bump