Next.js Discord

Discord Forum

cookies set error

Unanswered
Himalayan posted this in #help-forum
Open in Discord
HimalayanOP
i just setup for handle refreshToken from BE but when i will set the cookie the error is happen
Error: Cookies can only be modified in a Server Action or Route Handler

//satellite.ts
async function satellite(path: string, options: RequestInit) { const makeRequest = async (token: string | null) => { if (!token) { return null; } const headers = { ...options.headers, Authorization:Bearer ${token}, }; const response = await fetch(${process.env.NEXT_PUBLIC_API_URL}${path}, { ...options, headers, }); if (response.status === 401) { return null; } return response; }; let token = await getCookie("accessToken"); let response = await makeRequest(token || null); if (!response) { token = await refreshToken(); if (token) { response = await makeRequest(token); } } if (!response) { throw new Error("Authentication failed"); } return response.json(); } export default satellite;

'use server' export async function refreshToken() { try { const response = await fetch(${process.env.NEXT_PUBLIC_API_URL}/auth/refresh-token, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ refreshToken: await getCookie("refreshToken"), }), } ); if (!response.ok) { await deleteCookie("accessToken"); await deleteCookie("refreshToken"); redirect("/login"); } const data = await response.json(); const accessToken = data.data.accessToken; await setCookie("accessToken", accessToken); return accessToken; } catch (error) { console.error("Error refreshing token:", error); // Handle token refresh failure (e.g., redirect to login) throw error; } }

3 Replies

HimalayanOP
oke sorry
so this for handle fetch
//satellite.ts
import { getCookie, refreshToken } from "@/lib/cookies";
async function satellite(path: string, options: RequestInit) {
  const makeRequest = async (token: string | null) => {
    if (!token) {
      return null;
    }

    const headers = {
      ...options.headers,
      Authorization: `Bearer ${token}`,
    };

    const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}${path}`, {
      ...options,
      headers,
    });

    if (response.status === 401) {
      return null;
    }

    return response;
  };

  let token = await getCookie("accessToken");
  let response = await makeRequest(token || null);

  if (!response) {
    token = await refreshToken();
    if (token) {
      response = await makeRequest(token);
    }
  }

  if (!response) {
    throw new Error("Authentication failed");
  }

  return response.json();
}

export default satellite;
//cookies.ts
"use server";
import { cookies } from "next/headers";
import { redirect } from "next/navigation";

export const getCookie = async (name: string) => {
  const store = await cookies();
  return store.get(name)?.value;
};

export const setCookie = async (name: string, value: string) => {
  const store = await cookies();
  store.set(name, value, {
    httpOnly: true,
    path: "/",
  });
};

export const deleteCookie = async (name: string) => {
  const store = await cookies();
  store.delete(name);
};

export async function refreshToken() {
  try {
    const response = await fetch(
      `${process.env.NEXT_PUBLIC_API_URL}/auth/refresh-token`,
      {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          refreshToken: await getCookie("refreshToken"),
        }),
      }
    );

    if (!response.ok) {
      await deleteCookie("accessToken");
      await deleteCookie("refreshToken");
      redirect("/login");
    }

    const data = await response.json();
    const accessToken = data.data.accessToken;
    await setCookie("accessToken", accessToken);
    return accessToken;
  } catch (error) {
    console.error("Error refreshing token:", error);
    // Handle token refresh failure (e.g., redirect to login)
    throw error;
  }
}
and for the consume API
postsFetcher.ts
export const getAllPosts = async (query: URLSearchParams) => {
  try {
    const queryString = query.toString();
    const response = await satellite(`/posts?${queryString}`, {
      method: "GET",
      headers: {
        "Content-Type": "application/json",
      },
    });

    return response;
  } catch (error) {
    console.log("[ERROR]: ", error);
    throw error;
  }
};