Route handler not setting cookies
Unanswered
Yellow Warbler posted this in #help-forum
Yellow WarblerOP
Here is the route handler response:
(i assure that data is NOT null)
server component:
while the set-cookie header IS being set, chrome devtools is not showing any cookies and cookies().getAll() prints an empty array aswell
return new Response(data, {
status: 200,
headers: {
"Set-Cookie": `at=${data.accessToken}; Path=/; HttpOnly; SameSite=strict, rt=${data.refreshToken}; Path=/; HttpOnly; SameSite=strict`,
},
});(i assure that data is NOT null)
server component:
export default async function Home() {
const data = await fetch("http://127.0.0.1:3000/api/login", {
method: "POST",
credentials: "include",
mode: "cors",
cache: "no-store",
});while the set-cookie header IS being set, chrome devtools is not showing any cookies and cookies().getAll() prints an empty array aswell
23 Replies
@Yellow Warbler Here is the route handler response:
ts
return new Response(data, {
status: 200,
headers: {
"Set-Cookie": `at=${data.accessToken}; Path=/; HttpOnly; SameSite=strict, rt=${data.refreshToken}; Path=/; HttpOnly; SameSite=strict`,
},
});
(i assure that data is NOT null)
server component:
ts
export default async function Home() {
const data = await fetch("http://127.0.0.1:3000/api/login", {
method: "POST",
credentials: "include",
mode: "cors",
cache: "no-store",
});
while the set-cookie header IS being set, chrome devtools is not showing any cookies and cookies().getAll() prints an empty array aswell
Dont fetch your own api routes inside server side environments:
* https://discord.com/channels/752553802359505017/752647196419031042/1131131403707371562
* https://nextjs-discord-common-questions.joulev.dev/fetching-own-api-endpoint-in-react-server-components
* https://discord.com/channels/752553802359505017/752647196419031042/1131131403707371562
* https://nextjs-discord-common-questions.joulev.dev/fetching-own-api-endpoint-in-react-server-components
@joulev Dont fetch your own api routes inside server side environments:
* https://discord.com/channels/752553802359505017/752647196419031042/1131131403707371562
* <https://nextjs-discord-common-questions.joulev.dev/fetching-own-api-endpoint-in-react-server-components>
Yellow WarblerOP
I think maybe I should have added some additional context:
I am fetching a Next route handler that is fetching my (external) backend api. I know this isn't the best solution, but I could not figure out any other way to set cookies
I am fetching a Next route handler that is fetching my (external) backend api. I know this isn't the best solution, but I could not figure out any other way to set cookies
My original problem was this:
^ This would respond with the correct
Server component fetches next route handler
Route handler fetches external api
Route handler sets cookies
Route handler returns response
const res = await fetch(
`${process.env.NEXT_PUBLIC_API_URL_LOCAL}/auth/login`,
{
method: "POST",
credentials: "include",
mode: "cors",
headers: {
"Content-Type": "application/json",
},
cache: "no-store",
body: JSON.stringify({
email,
password,
}),
}
);
if (!res.ok) {
return NextResponse.json(null);
}
return await res.json();^ This would respond with the correct
set-cookie header, but the cookies would never actually set. So my workaround was toServer component fetches next route handler
Route handler fetches external api
Route handler sets cookies
Route handler returns response
If i'm doing something way wrong then please correct me (i've been trying to fix this all day)
@Yellow Warbler My original problem was this:
const res = await fetch(
`${process.env.NEXT_PUBLIC_API_URL_LOCAL}/auth/login`,
{
method: "POST",
credentials: "include",
mode: "cors",
headers: {
"Content-Type": "application/json",
},
cache: "no-store",
body: JSON.stringify({
email,
password,
}),
}
);
if (!res.ok) {
return NextResponse.json(null);
}
return await res.json();
^ This would respond with the correct `set-cookie` header, but the cookies would never actually set. So my workaround was to
Server component fetches next route handler
Route handler fetches external api
Route handler sets cookies
Route handler returns response
for the cookie to work, basically the Set-Cookie header must be send to the browser
@joulev for the cookie to work, basically the Set-Cookie header must be send to the browser
Yellow WarblerOP
Is it possible to send cookies through the server? This is for SSR reasons
so if you use a different backend and use a route handler to proxy to it, you must retrieve the header in the route handler and attach it to the response too
Yellow WarblerOP
ill look into that real quick
@Yellow Warbler Is it possible to send cookies through the server? This is for SSR reasons
it is disabled for security reasons; it doesn't make sense for a server to have cookies
cookies only apply to browsers
@joulev so if you use a different backend and use a route handler to proxy to it, you must retrieve the header in the route handler and attach it to the response too
Yellow WarblerOP
return new Response(data, {
status: 200,
headers: {
...res.headers, <-- is this what you mean?
"set-cookie": `at=${data.accessToken}; Path=/; HttpOnly; SameSite=strict, rt=${data.refreshToken}; Path=/; HttpOnly; SameSite=strict`,
},
});@Yellow Warbler
return new Response(data, {
status: 200,
headers: {
...res.headers, <-- is this what you mean?
"set-cookie": `at=${data.accessToken}; Path=/; HttpOnly; SameSite=strict, rt=${data.refreshToken}; Path=/; HttpOnly; SameSite=strict`,
},
});
something similar yes, though if you make another
set-cookie then the set-cookie inside res.headers will be overriden no?also you need to check whether
res.headers is a Header object or just a plain objectit would be easier if the backend sends the token in the form of response body, then the route handler reads the body and set the cookies there
@joulev also you need to check whether `res.headers` is a `Header` object or just a plain object
Yellow WarblerOP
const newHeaders = new Headers(res.headers);
return new Response(data, {
status: 200,
headers: {
...newHeaders,
},
});@joulev it would be easier if the backend sends the token in the form of response body, then the route handler reads the body and set the cookies there
Yellow WarblerOP
Oh yeah I tried doing this but
cookies().set() would not set anything for some reasoneven when I tested just doing this:
export async function POST(request: Request) {
cookies().set("hi", "bye");
// return
}const data = await fetch("http://127.0.0.1:3000/api/login", {
method: "POST",
cache: "no-store",
credentials: "same-origin",
mode: "cors",
});@Yellow Warbler even when I tested just doing this:
export async function POST(request: Request) {
cookies().set("hi", "bye");
// return
}
const data = await fetch("http://127.0.0.1:3000/api/login", {
method: "POST",
cache: "no-store",
credentials: "same-origin",
mode: "cors",
});
the
await fetch is from the browser right@joulev the `await fetch` is from the browser right
Yellow WarblerOP
Yes
'use client'
in that case try this
const response = new NextResponse(...);
response.cookies.set("hi", "bye")untested but it does sound like it should work
Northeast Congo Lion
I'm looking at this error on my own system, very similar problem, using fetch api etc. Response.cookies is undefined.