Skip to content

v4: Session is expired, but after Server Action is called i dont get redirected #1934

@BratislavZ

Description

@BratislavZ

Checklist

Description

I wanted to see how my app behaves when the session is expired and i call a server action.
In prev version (v3.5) server action would be called and then await getAccessToken would throw an error after which I would just redirect to api/auth/login . But in the current v4 the error is thrown before an action has started. Which is ok, Im creating a POST request when i want to call a server action and Auth0 can see in the middleware that I dont have session.
The issue is that the middleware sees the session is null and calls:

return NextResponse.redirect(new URL("/auth/login", req.url), {
  status: 303,
});

I can see in the terminal that the new path is /auth/login but browser is still showing page from which I initiated Server Action. In the browser Network I can see 3 requests:

Image

My middleware looks like this:

import { NextRequest, NextResponse } from "next/server";
import createIntlMiddleware from "next-intl/middleware";
import { routing } from "./i18n/routing";
import { auth0 } from "./lib/auth0";

const intlMiddleware = createIntlMiddleware(routing);

const loginPages = ["/", "/en-US"] as const;

export default async function middleware(req: NextRequest) {
  const pathname = req.nextUrl.pathname;
  const isLoginPage = loginPages.some((page) => page === pathname);
  const isProtectedPage = !isLoginPage
  const authResponse = await auth0.middleware(req);

  console.log("👀 Path:", pathname);

  if (pathname.startsWith("/auth")) {
    return authResponse;
  }

  const session = await auth0.getSession(req);

  console.log("🔥 Session:", session);

  // User is not logged in and tries to access a page that requires authentication
  if (!session && isProtectedPage) {
    return NextResponse.redirect(new URL("/auth/login", req.url), {
      status: 303,
    });
  }

  // Apply intl middleware
  const intlResponse = intlMiddleware(req);

  // Add Auth0 headers to the response
  for (const [key, value] of authResponse.headers) {
    intlResponse.headers.set(key, value);
  }

  return intlResponse;
}

export const config = {
  matcher: [
    "/",

    "/(en-US|is|de)/:path*",

    "/auth/:path*", // Make sure Auth0 routes are included

    "/((?!_next/image|_next/static|images|api|favicon.ico|_vercel|.*\\..*).*)",
  ],
};

My logs in the terminal:

👀 Path: /en-US/user-management/1/departments 
🔥 Session: null 
👀 Path: /auth/login

Browser logs:

Image

Reproduction

  1. Set auth0 server client:
export const auth0 = new Auth0Client({
  authorizationParameters: {
    audience: process.env.AUTH0_AUDIENCE,
  },
  session: {
    absoluteDuration: 15, // short session so I can test how app behaves after session is expired
  },
});
  1. Set middleware I provided in the description
  2. Call a server Action after the session is expired

Additional context

next-intl

nextjs-auth0 version

v4.02

Next.js version

v15.1.7

Node.js version

v20.10.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    V4ackbugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions