Next.js Discord

Discord Forum

NextJs middleware sets cookies after page/req to page loads

Unanswered
Trigg Hound posted this in #help-forum
Open in Discord
Trigg HoundOP
I'm not entirely sure how to word the title because it sounds awkward. However I'm going to try my best to explain what's going on here.

In my middleware I have a function that looks for both an access token and a refresh token to which works as expected.
async function refreshToken(req: NextRequest): RefreshTokenResponse {
  const token = req.cookies.get("access_token")?.value;
  const refreshToken = req.cookies.get("refresh_token")?.value;

  console.log({ token, refreshToken });

  if (token && refreshToken) return { redirect: "continue" };

  if (!refreshToken) {
    console.log("Refresh token not found\n");
    return {
      redirect: "login",
      message: "Unauthorized",
    };
  }

  if (!token && !refreshToken) {
    console.log("No tokens provided\n");
    return {
      redirect: "login",
      message: "Unauthorized",
    };
  }

  console.log("fetching new tokens");

  const formBody = [
    `${encodeURIComponent("grant_type")}=${encodeURIComponent("refresh_token")}`,
    `${encodeURIComponent("refresh_token")}=${encodeURIComponent(refreshToken)}`,
  ];
  const body = formBody.join("&");

  const response = await fetch(`${env.DB_API_URL}/auth/token`, {
    body,
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
  });

  const data = (await response.json()) as Response;

  if (!response.ok || "error" in data) {
    console.log("Error refreshing token", data);
    return {
      redirect: "login",
      message:
        "error" in data ? data.error_description : "Failed to refresh tokens",
    };
  }

  console.log("data", data);

  return {
    data,
    redirect: "token",
  };
}


after this function runs it checks to see if it continues, returns to login, or handles token values else where. After that it performs an auth check on the route here

  const result = checkPermission(
    req.nextUrl.pathname,
    response.data.access_token,
  ); // returns boolean

  // checks result and handles if the result is false
  if (!result) {
    //....  
  }

  const res = NextResponse.next();

  res.cookies.set("access_token", response.data.access_token, {
    path: "/",
    httpOnly: true,
    expires: new Date(Date.now() + response.data.expires_in),
  });

  res.cookies.set("refresh_token", response.data.refresh_token, {
    path: "/",
    httpOnly: true,
    expires: new Date(Date.now() + 172_800_000),
  });

  return res;


However, if the page/server action requires the access_token that hits the middleware, when the request finishes I get redirected to login because of how I get and check my auth token. When the middleware request finishes the token is always undefined, and only after it gets redirected to login. does the value appear in my cookies.
// function that retrieves access token
export const getToken = (): string | never => {
  const token = cookies().get("access_token")?.value;
  console.log("READING_TOKEN_VALUE", token);

  if (!token) {
    console.log("No token found. Redirecting to login");
    return redirect("/login");
  }

  return token;
};


I hope I explained this well enough to give context on the issue, if more context is required I will provide it. Thank you in advance!!

edit: To provide more context on this issue, just I can't get the updated token, until after the page fully renders itself out, only then am I able to get the updated access/refresh tokens

1 Reply

Brown bear