I created a simple public Lambda function that returns a simple HTML page. I have a custom domain with SSL setup (via Cloudfront). Everything works except it can't create a cookie when using the custom domain.
The Lambda uses the (relatively new) URL capability, and provides the URL https://xxxxxxxx.lambda-url.us-east-1.on.aws. AUTH type is set to none (e.g. public).
In order to access the Lambda via a custom URL (map.mydomain.com), I setup a Cloudfront distribution with a SSL certificate for that subdomain (map.mydomain.com).
So I can access the Lambda via either the AWS-provided URL or via the custom domain map.mydomain.com.
The only thing NOT working is setting a cookie, when using the custom domain.
The Lambda returns (for example) the following:
{
:statusCode=>200,
:body=>"<!DOCTYPE html><html><head><meta charset='UTF-8'>
</head><body>Cookie set to FOO</body></html>",
:headers=>{
:"Content-Type"=>"text/html",
:"Set-Cookie"=>"my_cookie_name=FOO; Path=/; Max-Age=300; Secure; SameSite=None;"
}
}
What Works: When I access the Lambda via the AWS-provided URL, I can see the cookie and its contents in my browser's Developer tools.
What Doesn't: If I access the Lambda via map.mydomain.com, I see the HTML page, but the browser's Developer tools shows no cookies for the domain.
I had thought perhaps that adding "Secure; SameSite=None;" to the Set-Cookie header would solve the issue, but it didn't.
I also turned on CORS for the Lambda "Function URL" setting, with Allow Origin set to the wildcard (*), and "credentials" turn ON.
Using curl -v -X GET <url> (or the Network tab in browser's Developer tools) I do see the "Set-Cookie" header when browsing the Lambda Function URL, and I do not see a "Set-Cookie" header when browsing the custom domain URL... so that "Set-Cookie" header is being removed somewhere between the browser and the lambda function.
Specifically, here is the response returned by the Lambda in response to a curl request. (Note the Lambda sends a "Set-Cookie" header. I tried both with and without "Domain=FOO.MYDOMAIN.NET;" in the header, same result the set-cookie header does not arrive with the html.)
{:statusCode=>200,
:body=>"<!DOCTYPE html><html><head><meta charset='UTF-8'></head><body>Cookie set to rand82_1652845019</body></html>",
:headers=>{
:"Content-Type"=>"text/html",
:"Set-Cookie"=>"cookie_ktree=rand82_1652845019; Path=/; Domain=FOO.MYDOMAIN.NET; Max-Age=300; Secure; SameSite=None;",
:"Access-Control-Allow-Origin"=>"*",
:"Access-Control-Allow-Credentials"=>true
}
}
And here is what the curl command received (note the absence of any Set-Cookie" header)
curl -v -X GET https://FOO.MYDOMAIN.NET/SOME-TESTURL
Note: Unnecessary use of -X or --request, GET is already inferred.
* Trying X.X.X.X...
* TCP_NODELAY set
* Connected to FOO.MYDOMAIN.NET (X.X.X.X) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=FOO.MYDOMAIN.NET
* start date: May 13 00:00:00 2022 GMT
* expire date: Jun 11 23:59:59 2023 GMT
* subjectAltName: host "FOO.MYDOMAIN.NET" matched cert's "FOO.MYDOMAIN.NET"
* issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7fad78008200)
> GET /SOME-TESTURL HTTP/2
> Host: FOO.MYDOMAIN.NET
> User-Agent: curl/7.64.1
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 200
< content-type: text/html
< content-length: 107
< date: Wed, 18 May 2022 03:36:59 GMT
< x-amzn-requestid: 7a013097-14d6-462e-9ca5-ae1a2fdd03fb
< access-control-allow-origin: *
< x-amzn-trace-id: root=1-628469db-680ee5ca7b9e5bf75b9e5b8c;sampled=0
< access-control-allow-credentials: true
< x-cache: Miss from cloudfront
< via: 1.1 fb4c985c6e0ddb6f82a2dffdde62d23e.cloudfront.net (CloudFront)
< x-amz-cf-pop: MIA3-P3
< x-amz-cf-id: YBVjC-na0PvGljCnr7fNUSu1q87L1e7V8gcZZL0YdDDeeyJnFS6UzQ==
<
* Connection #0 to host FOO.MYDOMAIN.NET left intact
<!DOCTYPE html><html><head><meta charset='UTF-8'></head><body>Cookie set to rand82_1652845019</body></html>* Closing connection 0
What else could I try to get the Lambda to set a cookie when using a custom domain?