5

I'm building an applciation with Next.js that is purely for authenticating the users through JWT's, and then redirecting them to our main web application. Before the Next.js version 12 release I have used next-connect to run one middleware function on every api request to deserialize the user from the token or refreshing the access token if the refresh token is expired. I now wanted to move from next-connect to the new api middleware but first of all I'm not sure how these functions would perform in an self hosted environment, because with Vercel they would be deployed as edge functions but how do they work in a self hosted environment? Just as normal express middleware or not at all?

I also get the error eval not allowed in Middleware pages/api/_middleware because the standard jsonwebtoken package is not allowed in edge functions. This issue states that I would have to use the lightweight package @tsndr/cloudflare-worker-jwt, even though I'm not planing to use edge functions but rather deploy the app myself.

This is the middleware I'm trying to run through the _middleware file on every api request:

export async function middleware(req: NextApiRequestWithUser) {
  const { access_token, refresh_token } = req.cookies;

  if (!access_token) {
    return NextResponse.next();
  }

  try {
    // Verify token
    const { payload, expired } = verifyAccessToken(access_token);

    if (payload) {
      if (!payload.userId) {
        return new Response("User id is missing in JWT payload.", {
          status: 401,
        });
      }
      const currentUser = await User.findById(payload.userId).lean();
      if (!currentUser) {
        return new Response(
          "The user belonging to this token no longer exist.",
          {
            status: 401,
          }
        );
      }
      req.user = currentUser;
    }

    const { payload: refreshPayload } = verifyRefreshToken(refresh_token);

    if (!refreshPayload) return NextResponse.next();

    const user = await User.findOne({ _id: refreshPayload.userId });

    if (user?.refreshToken === refresh_token && expired) {
      console.log("Refreshing access token");
      const newAccessToken = generateAccessToken(refreshPayload.userId);
      NextResponse.next().cookie(access_token, newAccessToken, {
        domain: "localhost",
        httpOnly: true,
        secure: process.env.NODE_ENV === "production",
        path: "/",
      });
      return NextResponse.next();
    }

    return NextResponse.next();
  } catch (error) {
    console.log(error);
    return NextResponse.next();
  }
}

2 Answers 2

2

Yes you can run Next.js middleware in a self hosted environment. And that eval not allowed error you're referring to is actually just a warning. More details about it can be found in this Github issue. User gustavo-dev gave an insightful explanation on the difference between Edge Functions and middleware:

Edge Functions are similar to CDN's (but different).

A CDN (Content Delivery Network) is used to serve static content in a fast way. Therefore they need to be located close to the client. The downside with this approach is the inability to deliver custom content to different clients based on their location, for example.

Another method that could solve this would be processing each request on the server (SSR). However, the drawback now is speed because the server handling these requests is not necessarily close to your end-user.

That's where Edge Functions come in! They work just like a CDN but they allow you to run server-side logic on the Edge, close to your client, which enables us to achieve both speed and dynamism.

A middleware, on the other hand, is a function that runs before a request is completed. If you've used ExpressJs before, you should be familiar with this concept. They can modify the request/response objects and are useful for authentication, among other things.

Hence, Middlewares are not necessarily Edge Functions and Edge Functions are not necessarily Middlewares. However, when deploying to Vercel, Middleware is the only code that runs in Edge Functions.

Sign up to request clarification or add additional context in comments.

Comments

1

Context:

I had this issue, spent hours searching for a solution, and now sharing, so next-js middlewares are something called edge functions and don't worry I don't know sh*t about this too, the whole thing is you can't run the dependency on middleware because it contains something called dynamic code and NOT "eval",

case 1: your JWT dependency or any other dependency has an issue with next-js middleware.

  • use another dependency, you have to find another dependency for your use case, eg for "jsonwebtoken", there's another dependency called jose

case 2: a low chance you're writing dynamic code like "eval".

  • just find a way around the dynamic code you're writing

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.