7

I am on a website https://aaa.shared.com. This website (call it A) sends an xhr request to url https://zzz.shared.com/some/path (website Z) and receives a response with the following headers:

access-control-allow-credentials: true access-control-allow-origin: aaa.shared.com set-cookie: foo=bar; expires=Fri, 01 Jan 2100 00:00:00 GMT; path=/; secure; samesite=none; httponly 

(I followed answer on this question to add access-control headers)

Now, what I would expect is that whenever I am on both A or Z, whenever a request goes to Z (cross-origin or same-origin, what matters is URL of the request) browser would add the cookie, but it doesn't! Moreover, I cannot see it being set in browser Developer Tools (F12 -> Application -> Cookies). I am using Chrome, but aiming for a cross browser solution.

What am I missing? I am finding it really hard to find some elaborate information on how Set-Cookie header works when requesting a different origin.

EDIT: rowan_z originally suggested to replace samesite=lax to samesite=none, as A and Z in the first version of this question were completely separate domains (shared only .com part). I tried it and it didn't help. But now I realise that they are actually regarded as SameSite, because they are on the different subdomains of shared.com domain. So now I believe that samesite=lax should have worked here as well.

UPDATE: In the end, I just moved the application aaa.shared.com under same subdomain with some path zzz.shared.com/aaa/path, as dealing with cookies and CORS is really tough. Also, configuring it to work with localhost adds extra complications.

1
  • Set the cookie`s domain to "shared.com", as described here: stackoverflow.com/a/60730433/4448410 You are not setting the Domain property at all, so by default it may be set to "aaa.shared.com" Commented Mar 20, 2020 at 20:24

2 Answers 2

5
+50

All of the things you did are indeed required to make it work:

  • access-control-allow-credentials: true
  • access-control-allow-origin: aaa.shared.com (not a wildcard)
  • Secure
  • SameSite=None

You were just missing one thing when sending the request: credentials: 'include'.

I've created a mock endpoint that you can use to test this line of code twice (in the console of another domain):

fetch('https://stackoverflow.free.beeceptor.com', { credentials: 'include' }); 

You'll notice the cookie will be sent the second time.

In case the mock endpoint expires (no idea how long it lasts), or if someone destroys it, you can recreate it on http://beeceptor.com with this JSON in the header configuration:

{ "Content-Type": "application/json", "Set-Cookie": "test=value; Path=/; Secure; SameSite=None;", "access-control-allow-origin": "https://yourdomain", "Access-Control-Allow-Credentials": "true" } 
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. Another bit I had to figure out myself was that browser actually sends an OPTIONS request for a GET in this case (I assume this is because we ask for credentials). And Chrome recently made OPTIONS requests not visible in the Dev Tools anymore, so the error I was getting was a bit misleading, as it seemed to be complaining about a GET response when in reality it was complaining about OPTIONS request. Realising that, I just reenabled OPTIONS request trace following this SO answer
Yes the OPTIONS is because the cookie makes the request "non simple" (this is a term from the HTTP spec) and that triggers a preflight request to check if the endpoint actually accepts the request we are about to send. This is explained pretty clearly here: developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Simple_requests
1

You have explicitly stated SameSite=Lax which restricts cookies from being sent on cross-site requests. This looks like a situation where you want SameSite=None to allow those cookies.

More detail on: https://web.dev/samesite-cookies-explained

3 Comments

hi, thanks, good spot. I added samesite=none as in your great article. Unfortunatelly it doesn't seem to solve the problem for me. The cookie is still not set and not sent
Any ideas what else might be going on here would be greatly appreciated
Actually, this might be even more interesting, I have updated the question. My domain A and domain Z probably are SameSite, because look like xxx.sss.com and yyy.sss.com (they are subdomains of the same sss.com domain`)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.