Does Sanctum (or Laravel) cookie-based session require me to have Laravel deployed to the root folder?
My application lives in a monorepo with server
, client
and some other folders, with server
folder containing Laravel 11 (used as backend API) and client
folder containing Vue 3 SPA. The setup works okay when deployed to a docker container, but deploying it to a shared hosting results in the following strange issue:
Issuing login/logout commands works correctly in that I get the expected response body, but somehow subsequent calls to the server do not recognize the request as authenticated. For example, doing Auth::check()
in the subsequent request returns false
. My feeling is that this has got something to do with the cookies not be set correctly.
I have spent time to make sure I'm not doing any of the usual mistakes:
SESSION_DOMAIN
, SANCTUM_STATEFUL_DOMAINS
are set correctly on the server.
Since Laravel is in the public_html/server
subfolder, I have the following .htaccess
in the root:
RewriteEngine On
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
RewriteCond %{REQUEST_URI} ^/api/ [OR]
RewriteCond %{REQUEST_URI} ^/storage/
RewriteRule ^ server/public/$1 [L]
RewriteCond %{DOCUMENT_ROOT}/server/public%{REQUEST_URI} -f
RewriteRule ^(.*)$ server/public/$1 [L]
RewriteRule ^ server/public/index.php [L]
and the usual Laravel .htaccess
file in server/public
:
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
Could it be that one of these .htaccess
files is interfering with how Sanctum issues/recognizes its cookies?
This turned out to be a problem with the value of SANCTUM_STATEFUL_DOMAINS
environment variable. While it worked correctly with https://${APP_NAME}
on the local docker container, I had to specify www.
prefix on production server. To be safe I then added all possible combinations with and without https
and www
:
SANCTUM_STATEFUL_DOMAINS=https://${APP_NAME},https://www.${APP_NAME},https://${APP_NAME}/,https://www.${APP_NAME}/,${APP_NAME},www.${APP_NAME}
It works correctly now.