Next.js Discord

Discord Forum

❗Unable to Save Payload to Session After Redirect from NestJS to Next.js App Router API

Unanswered
American Staffordshire Terrier posted this in #help-forum
Open in Discord
American Staffordshire TerrierOP
Hi everyone, I need some help here.

I'm working with a NestJS backend and a Next.js frontend (App Router). In my flow, NestJS handles OAuth (e.g. Google login), generates a token and payload, then redirects or POSTs the data to a Next.js API route (/api/login/callback).

In my Next.js API route, I try to:
- Retrieve the token (via URL or body)
- Set the cookie with cookies().set(...) (it works)
- Save tokenPayload into the session using getSession()
- Call session.save()

But for some reason, the session data (especially tokenPayload) is not being saved. No error is thrown — it just silently fails or doesn't persist.

I’ve confirmed that:
- The token is present
- The body is received correctly
- session.save() is awaited

What could I be doing wrong here?
Is it a bad idea to call cookies().set() before reading the request body with request.json()?
Any help would be really appreciated. 🙏

1 Reply

American Staffordshire TerrierOP
import { getSession } from "@/lib/session";
import { cookies } from "next/headers";
import { NextResponse } from "next/server";

export async function POST(request: Request) {
  try {
    const url = new URL(request.url);
    const token = url.searchParams.get("token");

    if (!token) {
      return new Response("Token missing", { status: 400 });
    }

    const requestBody = await request.json();

    if (requestBody.tokenPayLoad) {
      console.log("tokenPayLoad keys:", Object.keys(requestBody.tokenPayLoad));
      console.log("userId:", requestBody.tokenPayLoad.userId);
      console.log("role:", requestBody.tokenPayLoad.role);
    }

    const session = await getSession();

    // Assign dengan struktur yang eksplisit
    session.isLoggedIn = true;
    session.tokenPayLoad = {
      userId: requestBody.tokenPayLoad?.userId,
      role: requestBody.tokenPayLoad?.role,
    };
    session.expiresAt = Date.now() + 1000 * 60 * 60 * 24;

    console.log("Session after assignment:", JSON.stringify(session, null, 2));

    await session.save();

    // Verify immediately after save
    const freshSession = await getSession();
    console.log(
      "Fresh session after save:",
      JSON.stringify(freshSession, null, 2)
    );

    // Set cookie
    (await cookies()).set("Authentication", token, {
      httpOnly: true,
      secure: process.env.NODE_ENV === "production",
      path: "/",
      sameSite: "lax",
      expires: new Date(Date.now() + 1000 * 60 * 60 * 24),
    });

    return NextResponse.json({
      success: true,
      message: "Login berhasil",
      debug: {
        receivedData: requestBody.tokenPayLoad,
        savedData: freshSession.tokenPayLoad,
        isEqual:
          JSON.stringify(requestBody.tokenPayLoad) ===
          JSON.stringify(freshSession.tokenPayLoad),
      },
    });
  } catch (error) {
    return NextResponse.json(
      { success: false, message: "Server error", error: error },
      { status: 500 }
    );
  }
}