Next.js Discord

Discord Forum

awaiting the server action until cookie is present

Answered
keremaydemir posted this in #help-forum
Open in Discord
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?


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;

  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
  // it 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 };
}
Answered by Siberian Flycatcher
View full answer

3 Replies

Some actions actually gets the token at first try
  let token = cookies().get(HS_TOKEN_NAME)?.value;
  console.log("token first", token);
  /*
  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
  */
Siberian Flycatcher
Answer
Thank you so much Alex, it solved my problem 🫶