Does Sanctum (or Laravel) cookie-based session require me to have Laravel deployed to the root folder?
Background
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 inserver/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?
Does Sanctum (or Laravel) cookie-based session require me to have Laravel deployed to the root folder?
Background
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 inserver/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?
2 Answers
Reset to default 2I generally put my SPA and API backend on two separate domains (one pointing to a CDN and the other to the actual server) and deal with cookie issues a lot. However, that may not be entirely applicable to your circumstances since it appears you are using a single domain. Anyhow, hope these troubleshooting steps help:
A lot of the troubleshooting is probably on the frontend in the browser:
Did the browser receive the cookie?
This is most likely true since the login response was successful. Check the cookie values:
"domain": "example.",
"expires": "2025-03-03T16:06:18.000Z",
"httpOnly": true,
"path": "/",
"samesite": "None",
"secure": true,
"value": "..."
Is the domain
correct? Is the path
correct? Are the other values also correct?
Did the browser set the cookie?
You can check this by looking at the Storage
tab in Firefox and Chrome's Application > Storage
tab. If not, then the browser decided the cookie was invalid for some reason.
Are there CORS errors in the console?
This is more relevant to multi-domain set ups.. But if there are any errors, then it should tell you what is wrong with the cookie.
Sometimes there aren't any errors except for a little triangle warning badge next to the cookie in the request/response. You can hover your mouse over it and it'll tell you what is wrong.
Did the browser send the cookie back?
In the request, did it include the cookie? If not, then the domain/path is probably wrong. Check the values for domain
and path
again.
If the browser did send it back to the server, then the issue is likely that Apache isn't sending the cookie back to the Laravel app. At which point I am also at a loss without more information about the set up.
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.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745107837a4611664.html
www.
prefix in the website name. See my answer below. – dotNET Commented Mar 4 at 10:25