Until yesterday I had a pure API Laravel application successfully supporting two frontend applications. The frontend applications are not built from Laravel. Both frontends are on different domains and different from the backend too. The token-based Sanctum authentication was working fine.
Now I have added a third frontend application (cloned off one of the existing frontend applications) with its own (fourth) domain. This is not working fine.
Problem: in the new domain, Laravel returns success 204 to sanctum/csrf-cookie but Laravel’s response does not contain any Set-Cookie header for XSRF. Weirdly, this problem only exists when the request URL has no subdomain. When I add any random subdomain , everything works fine even though I get no Set-Cookie header in the response.
My case - multiple domains and multiple subdomains - seems not to be covered by the docs.
I have run php artisan cache:clear and php artisan config:clear
What’s happening?
+--------------------------------------+----------------------------------------------+
| | Laravel responds with Set-Cookie: XSRF-TOKEN |
+--------------------------------------+----------------------------------------------+
| my-backend-domain.com | |
+--------------------------------------+----------------------------------------------+
| my-frontend-domain1.com | YES |
+--------------------------------------+----------------------------------------------+
| anysubdomain.my-frontend-domain1.com | YES |
+--------------------------------------+----------------------------------------------+
| my-frontend-domain2.com | YES |
+--------------------------------------+----------------------------------------------+
| anysubdomain.my-frontend-domain2.com | YES |
+--------------------------------------+----------------------------------------------+
| my-frontend-domain3.com | NO |
+--------------------------------------+----------------------------------------------+
| anysubdomain.my-frontend-domain3.com | NO, but it works OK anyway |
+--------------------------------------+----------------------------------------------+
config/sanctum.php
(the .env file has no value)
'stateful' => explode(',', env(
'SANCTUM_STATEFUL_DOMAINS',
'http://localhost,localhost,localhost:3000,localhost:8004,127.0.0.1,127.0.0.1:8000,::1,my-frontend-domain1.com,my-frontend-domain2.com,my-frontend-domain3.com
)),
config/session.php
(the .env file has no value)
'domain' => env('SESSION_DOMAIN', null),
config/cors.php
'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,
Headers for my-frontend-domain2.com (working fine)
Request URL: https://www.my-frontend-domain1.com/sanctum/csrf-cookie
Request Method: GET
Status Code: 204 No Content
Remote Address: (address redacted)
Referrer Policy: strict-origin-when-cross-origin
REQUEST
GET /sanctum/csrf-cookie HTTP/1.1
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8,ja;q=0.7,zh;q=0.6
Cache-Control: no-cache
Connection: keep-alive
DNT: 1
Host: www.my-frontend-domain2.com
Pragma: no-cache
Referer: https://www.my-frontend-domain2.com/login
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36
sec-ch-ua: "Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
RESPONSE
HTTP/1.1 204 No Content
Server: nginx/1.18.0
Date: Sat, 11 Mar 2023 11:43:08 GMT
Connection: keep-alive
Cache-Control: private, must-revalidate
pragma: no-cache
expires: -1
Vary: Origin
Set-Cookie: XSRF-TOKEN=(330 characters redacted); expires=Sat, 11-Mar-2023 13:43:08 GMT; Max-Age=7200; path=/; samesite=lax
Set-Cookie: dbname_session=(330 characters redacted); expires=Sat, 11-Mar-2023 13:43:08 GMT; Max-Age=7200; path=/; httponly; samesite=lax
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Headers for laracastsiscool.my-frontend-domain3.com (working fine)
Request URL: https://laracastsiscool.my-frontend-domain3.com/sanctum/csrf-cookie
Request Method: GET
Status Code: 200 OK
Remote Address: (redacted)
Referrer Policy: strict-origin-when-cross-origin
REQUEST
GET /sanctum/csrf-cookie HTTP/1.1
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8,ja;q=0.7,zh;q=0.6
Cache-Control: no-cache
Connection: keep-alive
DNT: 1
Host: laracastsiscool.my-frontend-domain3.com
Pragma: no-cache
Referer: https://laracastsiscool.my-frontend-domain3.com/login
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36
sec-ch-ua: "Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
RESPONSE
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Sat, 11 Mar 2023 12:37:32 GMT
Content-Type: text/html
Content-Length: 4961
Last-Modified: Fri, 10 Mar 2023 17:09:44 GMT
Connection: keep-alive
ETag: "640b6458-1361"
Accept-Ranges: bytes
Headers for my-frontend-domain3.com (fails when no subdomain)
Request URL: https://my-frontend-domain3.com/sanctum/csrf-cookie
Request Method: GET
Status Code: 200 OK
Remote Address: (redacted)
Referrer Policy: strict-origin-when-cross-origin
REQUEST
GET /sanctum/csrf-cookie HTTP/1.1
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8,ja;q=0.7,zh;q=0.6
Cache-Control: no-cache
Connection: keep-alive
Cookie: dbname_session=(330 characters redacted)
DNT: 1
Host: my-frontend-domain3.com
Pragma: no-cache
Referer: https://my-frontend-domain3.com/login
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36
sec-ch-ua: "Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
RESPONSE
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Sat, 11 Mar 2023 11:41:30 GMT
Content-Type: text/html
Content-Length: 4961
Last-Modified: Fri, 10 Mar 2023 17:09:44 GMT
Connection: keep-alive
ETag: "640b6458-1361"
Accept-Ranges: bytes