I'm facing an issue since svelte last update. When I try to add multiple set-cookie in one request, only the first one is executed. I'm searching for 5 days, and I didn't find any solution.
Frontend - SvelteKit v1.0.0-next.234 Backend - Strapi 3.6.1 (v4.x.x not working with mongoDb if I understand well) Db - mongo
I call my login endpoint with my credentials (username, password), and wait for the jwt token response. When I receive it, I put it within other elements in my http request headers. In the hook.js file, I parse this header cookie and add it to my request.locals. Therefore, I can use my request locals within the getSession() method of the hooks.
Login.json.js endpoint
... all the query logic
const user = await login();
// ==> I get the jwt token
const cookieOptions = {
Secure: secure ? 'Secure;' : '',
httpOnly: true,
sameSite: sameSite,
path: "/",
maxAge: 60 * 60 * 24 * 7
}
const setUsername = cookie.serialize(`${COOKIE_NAME}`, user.user.username, cookieOptions);
const setJwt = cookie.serialize("jwt", user.jwt, cookieOptions);
const setCompId = cookie.serialize("_cId", user.user.company._id, cookieOptions);
// what worked before, but stop working after svelte framework update
const headers = {
'Set-Cookie': [setUsername, setJwt, setCompId]
}
// what I do know to find a way to solve it
let headers = new Headers();
headers.append('Set-Cookie',setUsername);
headers.append('Set-Cookie',setJwt);
headers.append('Set-Cookie',setCompId);
// the response
return {
body: {
user
},
headers,
status: 200
}
I've tried to put a plain text cookie, something like this :
cookiename=myUserName; Max-Age=604800; Path=/; HttpOnly; SameSite=Strict, jwt=xxx.xxx.Xxx; Max-Age=604800; Path=/; HttpOnly; SameSite=Strict, _cId=sjckjsdhfjkqsdhfjk; Max-Age=604800; Path=/; HttpOnly; SameSite=Strict
Only the first cookie is set in the header and in the browser.
hook.js
In my hook file, I had to change the object received by the handle function du to Svelte update
From this
export async function handle({request,resolve}){
const cookies = cookie.parse(request.headers.cookie || "");
...
}
To this
export async function handle({event,resolve}){
let cookies = event.request.headers.get("cookie")
...
}
The problem is that I only have one cookie value instead of 3.
I didn't found the solution. I think I can pass all my arguments within the first cookie value, in my login response, but, I think it's not a good idea.
I'm asking for help, because I can't move on my project. My dashboard pages call depends on these 3 elements gathering first.
Thank you all
I've changed the code has suggested by Thommas
const headers = new Headers()
headers.append('Set-Cookie', [setUsername, setJwt, setCompId].join(','))
When I console.log the headers it's ok, I get my 3 elements separated with a comma.
console.log(headers.get('Set-Cookie'));
// => result string :
/*
MYCOOKIENAME=ItIsOk; Max-Age=604800; Path=/; HttpOnly; SameSite=Strict,jwt=xxx.xxxx.xxxx.xxxx.Xxx.etc...; Max-Age=604800; Path=/; HttpOnly; SameSite=Strict,_cId=ItIsOk; Max-Age=604800; Path=/; HttpOnly; SameSite=Strict
*/
But, when I look at the request headers in the hooks.js, I still get the first one.
console.log("==>\n",event.request.headers,"\n<==\n")
// result
{
accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7',
'cache-control': 'no-cache',
connection: 'keep-alive',
cookie: 'MYCOOKIENAME=ItIsOk',
host: 'localhost:3000',
pragma: 'no-cache',
referer: 'http://localhost:3000/login',
'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"macOS"',
'sec-fetch-dest': 'document',
'sec-fetch-mode': 'navigate',
'sec-fetch-site': 'same-origin',
'sec-fetch-user': '?1',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36'
}
May be my return object is wrong.
return {
body: {
user
},
headers,
status: 200
}
}
I you have any idea ! I'll continue working on this issue, because I totaly blocked !
This was discussed in
https://github.com/sveltejs/kit/issues/3460
you can use response.headers.append(headerName, headerValue)
to add a header without overwriting existing ones. Just call this for every set-cookie you need.