PDS
January 6, 2022, 1:49am
1
Hi,
I am using multiValueHeaders to return multiple cookies like this:
...
const sessionCookie = cookie.serialize('_auth', token, {
secure: process.env.ENV === 'production',
domain: process.env.ENV === 'production' ? '.mydomain.com' : 'localhost',
httpOnly: true,
path: '/',
maxAge: 3600
})
...
return {
'statusCode': 200,
'multiValueHeaders': {
'Set-Cookie': [sessionCookie, rbacCookie]
},
'headers': {
'Cache-Control': 'no-cache',
},
'body': JSON.stringify(body)
}
It works locally using netlify dev
, however, when I deploy the application it does not return any cookies.
If I return a single cookie in the headers, like this:
return {
'statusCode': 200,
'headers': {
'Set-Cookie': sessionCookie
'Cache-Control': 'no-cache',
},
'body': JSON.stringify(body)
}
It works fine in production. However, you can’t return multiple cookies this way as it throws an error.
I have trawled the docs and support forums, but I can’t resolve it.
Do you have any ideas why multiValueHeaders would not work in production or am I missing something obvious?
Thanks,
Paul
Hi @PDS
According to the Passing multiple Set-Cookie headers in the response section of Support for multi-value parameters in Amazon API Gateway | AWS Compute Blog you need to use multiValueHeaders
instead of headers
const response = {
isBase64Encoded: true,
statusCode: 200,
multiValueHeaders : {
"Set-Cookie": [
`language=${language}`,
`theme=${theme}`
]
},
body: JSON.stringify('User profile set successfully')
};
(Example from page.)
Though this looks similar to what you have…
I haven’t had need to try this myself, but am interested to see if this works for you.
Edit:
After deploying a simple test, this is the result I see
PDS
January 6, 2022, 2:16am
3
Hi @coelmay
Thanks for the swift reply.
I did try:
return {
'statusCode': 200,
'multiValueHeaders': {
'Cache-Control': 'no-cache',
'Set-Cookie': [sessionCookie, rbacCookie]
},
'body': JSON.stringify(body)
}
However, that returns a 502 in production, but still works ok locally.
Wrapping all headers in an array, again works locally, but in production, although it does not return a 502, it still does not return the cookies.
return {
'statusCode': 200,
'multiValueHeaders': {
'Cache-Control': ['no-cache'], <<<<<< pass value in array
'Set-Cookie': [sessionCookie, rbacCookie]
},
'body': JSON.stringify(body)
}
I picked up in this post that @ekafyi resolved his issue using both headers and multiValueHeaders:
" multiValueHeaders
can only contain the Set-Cookie
property. Anything else goes in headers
as usual."
Which or course I tried, but had not joy.
Thanks,
Paul
A little more tinkering and I get this…
This is the function I used
const cookie = require('cookie')
exports.handler = async (event, context, callback) => {
var language = "Toki Pona";
var theme = "Orange";
const sessionCookie = cookie.serialize('_auth', "KJASDIU34567ASKDGA", {
// secure: process.env.ENV === 'production',
domain: 'boring-joliot-18e93d.netlify.app',
httpOnly: true,
path: '/',
maxAge: 3600
});
console.log("Session Cookie %s",sessionCookie);
return {
// isBase64Encoded: true,
statusCode: 200,
headers: {
"Cache-Control": "no-cache"
},
multiValueHeaders : {
"Set-Cookie": [
`language=${language}`,
`theme=${theme}`,
`sessionCookie=${JSON.stringify(sessionCookie)}`,
]
},
body: JSON.stringify(`'User profile set successfully'`)
};
};
PDS
January 6, 2022, 3:02am
5
You have got me closer to working it out
If I simply add string values for the cookies:
multiValueHeaders: {
'Set-Cookie': [
'nf_jwt=token',
'_auth=token'
]
}
It works in production as expected by sending two cookies.
So it has to do with how I am serializing the cookie tokens.
It is a quite late my side, so I will work through it tomorrow. When I get it working I’ll post my result or mark your previous post as the solution.
I can’t thank you enough for your help - I was running out of steam.
Thanks,
Paul
1 Like
One issue is process.env.ENV
is meant to read process.env.NODE_ENV
.
And as I was reminded (I just never learn sometimes!) after a little searching
Only environment variables in the dashboard are available at the time of a function execution in Netlify Functions at the time of this answer.
So you need to set NODE_ENV
in the Netlify UI to production
.
This combined with the const sessionCooke = ...
you have and the multiValueHeaders
will work.
Example:
const cookie = require('cookie')
exports.handler = async (event, context, callback) => {
var token = "KJASDIU34567ASKDGA"
const sessionCookie = cookie.serialize('_auth', token, {
secure: process.env.NODE_ENV === 'production',
domain: process.env.NODE_ENV === 'production' ? '.mydomain.com' : 'localhost',
httpOnly: true,
path: '/',
maxAge: 3600
});
return {
statusCode: 200,
headers: {
"Cache-Control": "no-cache"
},
multiValueHeaders : {
"Set-Cookie": [
'language=Dansk',
sessionCookie
]
},
body: JSON.stringify(event.body)
};
};
Learned more about cookies today than any previous day of my life. Still prefer chocolate chip though
1 Like
PDS
January 6, 2022, 11:26am
7
@coelmay
Thank you. I indeed had an issue with the environment variables. I had changed them in my .env file and the portal to suit using a vite app, which require a prefix, and did not update the code. It seemed to fail silently and took a bit of trial and error to uncover that.
I have marked your answer as the solution as anyone following that example will have a good base to work from.
It is worth noting for anyone else reviewing this that the line:
domain: process.env.NODE_ENV === 'production' ? '.mydomain.com' : 'localhost',
is to allow the cookie to be used across subdomains.
I also learned a lot about cookies today and I agree - the edible ones are much better .
Thanks again.
Paul
1 Like