The problem:
In production my server and client are running in different origins (CORS).
The client needs to store a cookie sent from the server, but it fails to do so even that the cookie attributes are set as required.
The server is written in Flask and the client sends requests with Axios.
What I've tried so far and current status:
- First off, when the client and server are in the same origin (
localhost:3000
andlocalhost:5000
) the cookie is set as expected - To simulate CORS locally, I run the client in
127.0.0.1:3000
and the server inlocalhost:5000
.
The bug is reproduced in these settings. - I followed this post (and many others) and configured the server, client and the cookie as required, but still the cookie is not set in the browser
- Since this is a cross-origin request, a preflight
OPTIONS
request is sent first - Current status:
Preflight request headers:
OPTIONS /api/v0/get_csrf_token HTTP/1.1
Host: localhost:5000
Connection: keep-alive
Accept: */*
Access-Control-Request-Method: GET
Access-Control-Request-Headers: app-version,authorization,os-type
Origin: http://127.0.0.1:3000
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
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
Sec-Fetch-Dest: empty
Referer: http://127.0.0.1:3000/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Preflight response headers:
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Allow: HEAD, GET, OPTIONS
Access-Control-Allow-Origin: http://127.0.0.1:3000
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: app-version, authorization, os-type
Access-Control-Allow-Methods: DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT
Vary: Origin
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Security-Policy: default-src https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://rawgit.com; connect-src 'self' https://*.fontawesome.com; img-src 'self' data: https://*.amazonaws.com https://*.vizcloud.net https://*.viz.cloud; font-src 'self' https://maxcdn.bootstrapcdn.com https://fonts.googleapis.com https://fonts.gstatic.com https://*.fontawesome.com; script-src 'self' 'unsafe-inline' https://code.jquery.com https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://unpkg.com http://d3js.org https://rawgit.com https://*.fontawesome.com https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://code.jquery.com https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://fonts.googleapis.com https://rawgit.com https://*.fontawesome.com https://cdn.jsdelivr.net
X-Content-Security-Policy: default-src https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://rawgit.com; connect-src 'self' https://*.fontawesome.com; img-src 'self' data: https://*.amazonaws.com https://*.vizcloud.net https://*.viz.cloud; font-src 'self' https://maxcdn.bootstrapcdn.com https://fonts.googleapis.com https://fonts.gstatic.com https://*.fontawesome.com; script-src 'self' 'unsafe-inline' https://code.jquery.com https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://unpkg.com http://d3js.org https://rawgit.com https://*.fontawesome.com https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://code.jquery.com https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://fonts.googleapis.com https://rawgit.com https://*.fontawesome.com https://cdn.jsdelivr.net
Referrer-Policy: strict-origin-when-cross-origin
Content-Length: 0
Server: Werkzeug/0.16.0 Python/3.7.9
Date: Thu, 13 Jan 2022 09:06:31 GMT
Follow-up GET
request headers:
GET /api/v0/get_csrf_token HTTP/1.1
Host: localhost:5000
Connection: keep-alive
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"
sec-ch-ua-mobile: ?0
Authorization: null
Accept: application/json
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
os-type: 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
sec-ch-ua-platform: "macOS"
app-version: web
Origin: http://127.0.0.1:3000
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://127.0.0.1:3000/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie: X-CSRFToken=IjI1ODlkZGQ4MzJlMzRiZDM2M2U5YzgyM2EyODAxNTgxZTIyNDYwOWYi.FMF7UQ.-do_q8Zv3Fonh5QdSvfhaGbAVBk
Follow-up GET
response headers:
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 3
/*** THIS IS THE COOKIE I NEED TO STORE ***/
Set-Cookie: X-CSRFToken=IjFhYmVkNjZmN2Y0NjEzMTNmNzRhNzI4ZGVlZTVmMzQzNTVjN2JmOTgi.FMF9Fw.DWGaapFRX40GwpV3KU07iHEZzKc; Expires=2022-01-13 12:06:31.906331; SameSite=None; Path=/; Secure
Access-Control-Allow-Origin: http://127.0.0.1:3000
Access-Control-Allow-Credentials: true
Vary: Origin, Cookie
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Security-Policy: default-src https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://rawgit.com; connect-src 'self' https://*.fontawesome.com; img-src 'self' data: https://*.amazonaws.com https://*.vizcloud.net https://*.viz.cloud; font-src 'self' https://maxcdn.bootstrapcdn.com https://fonts.googleapis.com https://fonts.gstatic.com https://*.fontawesome.com; script-src 'self' 'unsafe-inline' https://code.jquery.com https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://unpkg.com http://d3js.org https://rawgit.com https://*.fontawesome.com https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://code.jquery.com https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://fonts.googleapis.com https://rawgit.com https://*.fontawesome.com https://cdn.jsdelivr.net
X-Content-Security-Policy: default-src https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://rawgit.com; connect-src 'self' https://*.fontawesome.com; img-src 'self' data: https://*.amazonaws.com https://*.vizcloud.net https://*.viz.cloud; font-src 'self' https://maxcdn.bootstrapcdn.com https://fonts.googleapis.com https://fonts.gstatic.com https://*.fontawesome.com; script-src 'self' 'unsafe-inline' https://code.jquery.com https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://unpkg.com http://d3js.org https://rawgit.com https://*.fontawesome.com https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://code.jquery.com https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://fonts.googleapis.com https://rawgit.com https://*.fontawesome.com https://cdn.jsdelivr.net
Referrer-Policy: strict-origin-when-cross-origin
Set-Cookie: session=eyJjc3JmX3Rva2VuIjoiMWFiZWQ2NmY3ZjQ2MTMxM2Y3NGE3MjhkZWVlNWYzNDM1NWM3YmY5OCJ9.FMF9Fw.r8g0VeK8PjVqEtWz6ZcJrVYg6fo; HttpOnly; Path=/
Server: Werkzeug/0.16.0 Python/3.7.9
Date: Thu, 13 Jan 2022 09:06:31 GMT
Notice that the X-CSRFToken
cookie in the GET
response headers has SameSite=None
and Secure
attributes, as required for CORS.
But when I inspect DevTools in Application -> Storage -> Cookies
, I see no cookies set in the browser.
You can also see the responses in the following images:
What am I missing?