admin管理员组

文章数量:1183786

Im using nextjs v14.2.8 with Keycloak for auth and i am hosting it in a pod using a Dockerfile. The output nextjs is standalone and im using basically the recomended next js with-docker .

I use the middleware to check the expiration date of the access_token, and if it is i send a refresh post request to keycloak to refresh it and then i set it in a cookie. Also im implemented some code that i found in a github forum, which helped me read the set cookies in the middleware, already in a server action and server components. The middleware code looks like this (im using a middleware chain, so this is the auth middleware):

import { NextResponse } from 'next/server';
...
import {
  ResponseCookies,
  RequestCookies,
} from 'next/dist/server/web/spec-extension/cookies';

/**
 * Copy cookies from the Set-Cookie header of the response to the Cookie header of the request,
 * so that it will appear to SSR/RSC as if the user already has the new cookies.
 */
function applySetCookie(req: NextRequest, res: NextResponse) {
  // 1. Parse Set-Cookie header from the response
  const setCookies = new ResponseCookies(res.headers);

  // 2. Construct updated Cookie header for the request
  const newReqHeaders = new Headers(req.headers);
  const newReqCookies = new RequestCookies(newReqHeaders);
  setCookies.getAll().forEach((cookie) => newReqCookies.set(cookie));

  // 3. Set up the “request header overrides” (see .js/pull/41380)
  //    on a dummy response
  // NextResponse.next will set x-middleware-override-headers / x-middleware-request-* headers
  const dummyRes = NextResponse.next({ request: { headers: newReqHeaders } });

  // 4. Copy the “request header overrides” headers from our dummy response to the real response
  dummyRes.headers.forEach((value, key) => {
    if (
      key === 'x-middleware-override-headers' ||
      key.startsWith('x-middleware-request-')
    ) {
      res.headers.set(key, value);
    }
  });
}

const protectedRoute = '/projects';

export function withAuthMiddleware(middleware: CustomMiddleware) {
  return async (
    request: NextRequest,
    event: NextFetchEvent,
    response: NextResponse
  ) => {
    const url = request.nextUrl;
    let res = response;

    const path = request.nextUrl.pathname;
    const isProtectedRoute = path.startsWith(protectedRoute);

    const cookie = request.cookies.get('session')?.value;

    if (!cookie) {
      return NextResponse.redirect(new URL('/auth/login', request.url));
    }

    const session = await decrypt(cookie);

    if (isProtectedRoute && !session) {
      return NextResponse.redirect(new URL('/auth/login', request.url));
    }

    if (session?.expires_at && isAccessTokenExpired(session.expires_at)) {
      console.log('middleware refreshing token');

      res = NextResponse.next();
      const updatedSession = await updateSession(session);
      console.log(updatedSession.expires_at);
      res.cookies.set('session', await encrypt(updatedSession), {
        name: 'session',
        httpOnly: true,
        secure: process.env.NODE_ENV === 'production',
        sameSite: 'lax',
        path: '/',
        expires: updatedSession.refresh_expires_in,
      });

      applySetCookie(request, res);
      return middleware(request, event, res);
    }

    return middleware(request, event, res);
  };
}

For some reason this works fine on dev and when locally creating a dockercontainer, but when i host it in a pod, i get 502 errors from nginx when the refresh fires off. And sometimes an api routehandler that also refreshes the token, only on the client side, isnt able to read the cookies saying that they are'nt set.

I've been struggling with this issue for 2 weeks now, and any help would really be appreciated.

For the technical details about the pod where its being hosted, i will need to check from my colleague which set it up and set up the nginx config, guessing for the Keycloak. (ps he's saying that nextjs server is for some reason restarting in the pod, but im not sure what could be the problem)

本文标签: nodejsNextjs middleware in production problems with setting cookiesStack Overflow