Trouble reading the cookie in server action, how to ensure that cookie is present? Next13

29 views Asked by At

I need a authorization token to successfully fetch APIs. If this token is not present in cookie I need to make a fetch request first and set the cookie with its response. I set this token as a cookie in 'middleware.ts' and read the cookie in a server action that is connected to all other server actions. The problem is that the cookie is already set and I see it in application tab, but I cannot read it properly in server action. How can I ensure that the token is present? I need to make sure that all fetch calls has that authorization header.

I have tried the headers object in next.config.js with Set-Cookie header, and it results same as middleware.

middleware.ts

import { NextResponse, type NextRequest } from "next/server"

import makeHandshake from "./services/auth/handshake"

const HS_TOKEN_NAME = process.env.HS_TOKEN_NAME!

export async function middleware(req: NextRequest): Promise<NextResponse> {
  const res = NextResponse.next()
  const token = req.cookies.get(HS_TOKEN_NAME)?.value

  if (!token) {
    const newToken = await makeHandshake()
    res.cookies.set(HS_TOKEN_NAME, newToken)
  }

  return res
}

export const config = {}
export default async function getServerDefaults(
  options: Options | undefined = undefined
): Promise<ServerDefaults> {
  const baseURL = process.env.NEXT_PUBLIC_API_BASE_URL!;
  const HS_TOKEN_NAME = process.env.HS_TOKEN_NAME!;

  let token = cookies().get(HS_TOKEN_NAME)?.value;
  console.log("token first", token);

  function sleep(ms: number): Promise<void> {
    return new Promise((resolve) => {
      setTimeout(resolve, ms);
    });
  }

  if (!token) await sleep(2000);
  // cookie is present in application tab but it doesn't read it
  // sleep works as expected all requests wait for 2 seconds, no problem there
  token = cookies().get(HS_TOKEN_NAME)?.value; // still no value

  let defaultHeaders = {
    "Content-Type": "application/json",
    Accept: "application/json",
    Authorization: `Bearer ${token}`,
  };

  if (options?.scope) {
    defaultHeaders = Object.assign(defaultHeaders, {
      "x-ob-scope": options.scope,
    });
  }

  const headers = new Headers(defaultHeaders);

  return { headers, baseURL };
}

console.log("token first", token) produces:

  some actions gets the token but not all of them

  token first undefined
  token first undefined
  token first undefined
  token first undefined
  token first undefined
  token first undefined
  token first undefined
  token first token123
  token first token123
0

There are 0 answers