"use server"; import { cookies } from "next/heade...

Creato il: 3 marzo 2025

Risposto usando O3 Mini High da Chat01

Domanda

"use server";

import { cookies } from "next/headers";

// import axios from "axios";
// Optional: Switch the Refresh Call to Axios

/**

  • Refresh the access token using the stored refresh token.
    */
    export async function handleRefresh() {
    console.log("handleRefresh");

const refreshToken = await getRefreshToken();
if (!refreshToken) {
// If there's no refresh token, just reset cookies and return
await resetAuthCookies();
return null;
}

try {
// You could switch this to axios if you prefer, but since
// this is a server-side call, using fetch is also fine.
const response = await fetch("http://localhost:8000/api/auth/token/refresh/", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({ refresh: refreshToken }),
});

text
const data = await response.json(); console.log("Response - Refresh:", data); if (data?.access) { // Store new access token in the cookies const cookieStore = cookies(); cookieStore.set("session_access_token", data.access, { httpOnly: true, secure: false, maxAge: 60 * 60, // 60 minutes path: "/", }); return data.access; } else { // If refresh fails or no "access" in response, reset everything await resetAuthCookies(); return null; }

} catch (error) {
console.error("Refresh error:", error);
await resetAuthCookies();
return null;
}
}

/**

  • Handle the login process by storing userId/accessToken/refreshToken as cookies.
    */
    export async function handleLogin(
    userId: string,
    accessToken: string,
    refreshToken: string
    ) {
    const cookieStore = cookies();

cookieStore.set("session_userid", userId, {
httpOnly: true,
secure: false,
maxAge: 60 * 60 * 24 * 7, // One week
path: "/",
});

cookieStore.set("session_access_token", accessToken, {
httpOnly: true,
secure: false,
maxAge: 60 * 60, // 60 minutes
path: "/",
});

cookieStore.set("session_refresh_token", refreshToken, {
httpOnly: true,
secure: false,
maxAge: 60 * 60 * 24 * 7, // One week
path: "/",
});
}

/**

  • Resets (clears) all authentication-related cookies.
    */
    export async function resetAuthCookies() {
    const cookieStore = cookies();

cookieStore.set("session_userid", "", { path: "/" });
cookieStore.set("session_access_token", "", { path: "/" });
cookieStore.set("session_refresh_token", "", { path: "/" });
}

/**

  • Retrieves the "session_userid" cookie (if any).
    */
    export async function getUserId() {
    const cookieStore = cookies();
    const userId = cookieStore.get("session_userid")?.value;
    return userId || null;
    }

/**

  • Retrieves the "session_access_token" cookie.
  • If it's missing, tries to refresh it once.
    */
    export async function getAccessToken() {
    const cookieStore = cookies();
    let accessToken = cookieStore.get("session_access_token")?.value;

if (!accessToken) {
accessToken = await handleRefresh();
}

return accessToken;
}

/**

  • Retrieves the "session_refresh_token" cookie (if any).
    */
    export async function getRefreshToken() {
    const cookieStore = cookies();
    const refreshToken = cookieStore.get("session_refresh_token")?.value;
    return refreshToken || null;
    }

[{
"resource": "/home/utopia/BSD/bsd/app/lib/actions.ts",
"owner": "typescript",
"code": "2339",
"severity": 8,
"message": "Property 'set' does not exist on type 'Promise<ReadonlyRequestCookies>'.",
"source": "ts",
"startLineNumber": 40,
"startColumn": 19,
"endLineNumber": 40,
"endColumn": 22,
"relatedInformation": [
{
"startLineNumber": 40,
"startColumn": 19,
"endLineNumber": 40,
"endColumn": 22,
"message": "Did you forget to use 'await'?",
"resource": "/home/utopia/BSD/bsd/app/lib/actions.ts"
}
]
}]

Pensiero

Fixing async cookies error

The error suggests that cookies() returns a Promise, so it's not immediately available in its resolved form. I think the issue comes from using cookieStore.set right after calling cookies() without awaiting it. The error message even hints at this — "Did you forget to use 'await'?"

To fix it, you’ll need to await the cookies() call, like:

ts
const cookieStore = await cookies(); cookieStore.set(...);

This should resolve the type mismatch issue.

Clarifying cookie handling in Next.js

In Next.js 13, when using server-side code, you need to await the cookies() function to get the actual object. Otherwise, it returns a Promise that resolves to a ReadonlyRequestCookies object, which doesn't have the set method. If you're trying to set cookies, check the API—maybe use headers().setCookie() instead of cookies().set(), depending on the context. The "cookies" function can be both read and write, but make sure it's awaited when used server-side.

Reasoned about cookie handling error for 12 seconds

Risposta

The error occurs because the call to cookies() returns a promise, and you need to await that promise before using its methods. TypeScript indicates that you're trying to call .set on a promise rather than on the resolved cookie store object.

To fix this, change your code from:

typescript
const cookieStore = cookies(); cookieStore.set("session_userid", userId, { ... });

to:

typescript
const cookieStore = await cookies(); cookieStore.set("session_userid", userId, { ... });

This ensures that cookieStore is the resolved object that contains the .set method, rather than a promise.

Condividi questa Q&A