Cookies get deleted after I perform this POST api request
Answered
Havana posted this in #help-forum
HavanaOP
I use discord authentication oauth2 method, which basically returns to me the access + refresh tokens.
In the dev mode it worked perfectly fine for me, but in production it just stops working.
Each time I try and trigger that api endpoint and the return value differs from the previous one it insta deletes the access and refresh token cookies (at, rt).
This is how I store the cookies after I authenticated and it works perfectly fine:
And this is the endpoint that screws the cookies:
In the dev mode it worked perfectly fine for me, but in production it just stops working.
Each time I try and trigger that api endpoint and the return value differs from the previous one it insta deletes the access and refresh token cookies (at, rt).
This is how I store the cookies after I authenticated and it works perfectly fine:
const response = NextResponse.json("http://localhost:3000/databases");
const accessTokenCookie = serialize("at", accessToken, {
httpOnly: true,
secure: false,
maxAge: 604800,
sameSite: "strict",
path: "/",
});
const refreshTokenCookie = serialize("rt", refreshToken, {
httpOnly: true,
secure: false,
maxAge: tokenExpirySeconds,
sameSite: "strict",
path: "/",
});
response.headers.append("Set-Cookie", accessTokenCookie);
response.headers.append("Set-Cookie", refreshTokenCookie);
return response;And this is the endpoint that screws the cookies:
import axios from "axios";
import { NextRequest, NextResponse } from "next/server";
import { RequestCookie } from "next/dist/compiled/@edge-runtime/cookies";
import db from "@/app/_utils/db";
export async function POST(req: NextRequest) {
let body;
try {
body = await req.json();
} catch (error) {
return new NextResponse("Invalid request body", { status: 400 });
}
try {
const {
accessToken: accessTokenArgument,
cookies: sentCookies,
}: { accessToken: string; cookies: Record<string, RequestCookie> } = body;
if (accessTokenArgument) {
try {
const UserData = (
await axios.get("https://discord.com/api/users/@me", {
headers: {
Authorization: `Bearer ${accessTokenArgument}`,
},
withCredentials: true,
})
).data;
if (!UserData) {
return new NextResponse("Failed to retrieve user's data", {
status: 401,
});
}
return NextResponse.json({ UserData }, { status: 200 });
} catch (error) {
return new NextResponse("Error retrieving user data", { status: 500 });
}
}
let accessToken = sentCookies?.at?.value;
if (!accessToken) {
return NextResponse.json("No AT", { status: 500 });
}
try {
const response = await axios.get("https://discord.com/api/users/@me", {
headers: { Authorization: `Bearer ${accessToken}` },
withCredentials: true,
});
const roles = await db.roles.findMany({
where: { user_id: response.data.id },
select: { role_name: true, color: true },
});
const { id, global_name, avatar } = response.data;
const user = await db.users.findFirst({ where: { uid: id } });
if (user) {
await db.users.update({
where: { uid: id },
data: { username: global_name, avatar },
});
}
const res = NextResponse.json(
{
UserData: response.data,
roles,
userPremium: user?.issubscribed,
},
{ status: 200 }
);
return res;
} catch (error) {
return new NextResponse("Internal Server Error", { status: 500 });
}
} catch (err) {
return new NextResponse("Internal Server Error", { status: 500 });
}
}Answered by "use php"
So you gave me access to the source.
And here is what I found:
- You had a link component in navbar
- That Link component was prefetching
- that resulted in a logout
And here is what I found:
- You had a link component in navbar
- That Link component was prefetching
/logout- that resulted in a logout
22 Replies
HavanaOP
Those are the server actions that trigger this POST request, I tried using the original function without caching, and it still didn't work:
import axios from "axios";
import { cache } from "../../_helpers/cache";
import {
RequestCookie,
RequestCookies,
} from "next/dist/compiled/@edge-runtime/cookies";
import { cookies } from "next/headers";
const emptyUser: Partial<Me> = {
id: "",
global_name: "",
avatar: "",
username: "",
};
export const getUserData = async (cookies?: Record<string, RequestCookie>) => {
try {
const response = await axios.post(
"http://localhost:3000/api/discord/getuserdata",
{ cookies },
{ withCredentials: true }
);
console.log(response.data);
return response.data;
} catch (error) {
return { UserData: emptyUser, roles: [], userPremium: false };
}
};
export const getUserDataCached = async (
cookies?: Record<string, RequestCookie>
) => {
const data = await getUserData(cookies);
const userId = data.UserData.id || "default";
return cache(() => getUserData(cookies), [`userData_${userId}`], {
revalidate: 60 * 60 * 20,
tags: ["userData"],
});
};
export const getUserDataProcess = async (
cookiesSent?: RequestCookies
): Promise<{
data: {
UserData: Me;
roles: { role_name: string; color: string }[];
userPremium: boolean;
};
}> => {
const cookieStore = cookies();
const cookiesToUse = cookiesSent ?? cookieStore;
const cookieHeaders = Object.fromEntries(cookiesToUse);
const data = await getUserDataCached(cookieHeaders);
return { data };
};I am using next 15 if it helps somehow, basically means that all routes are dynamic by default
Havana
@Havana aint NO ONE know the answer to your issue
HavanaOP

Havana
$5 to whoever solves this
Havana
@Paper wasp
@Havana
why do cookies get deleted in prod but not dev
Havana
@Multiflora rose seed chalcid
fix this I beg
@Havana <:sadness:1084117564717809855>
Blue swimming crab
hi, there.
i wanna ask you why you set { httpOnly: true}
@Blue swimming crab i wanna ask you why you set { httpOnly: true}
That means the client script can’t access it
@Blue swimming crab i wanna ask you why you set { httpOnly: true}
HavanaOP
for security, it doesnt make the bug occur
@Havana for security, it doesnt make the bug occur
Blue swimming crab
did you try to make it false?
same shit
I found the rarest bug I guess, its not about setting cookies, its about how I access them maybe
So you gave me access to the source.
And here is what I found:
- You had a link component in navbar
- That Link component was prefetching
- that resulted in a logout
And here is what I found:
- You had a link component in navbar
- That Link component was prefetching
/logout- that resulted in a logout
Answer
Right click > Apps > Mark solution
thanks