Hi, I have built an application that I am deploying using Laravel Forge across 3 environments: Dev, staging and prod.
The application is a CMS and an API which are accessible on 2 separate subdomains: admin.mydomain.com and api.mydomain.com.
The backend is built with Jetstream and Filament, and we are using Octane for tha web server.
Everything worked correctly up until recently. I have spent hours testing various solutions with no luck. In practice, on all environment if I leave the login page alone for 1 minutes, I get the 419. Once logged in, the same thing happens if I stay on the same page for more than about 1 minute. Please note that I am unable to replicate this behaviour on my local sail environment.
On the login form, I am monitoring the cookie, and after 1 minute, if I interact with the form, the cookies are refreshed, but not the CSRF in the metatag (not sure if this is as expected)
Here are details about my setup and things I have tested already:
Project config:
Laravel 10
PHP 8.3
Octane + Swoole
Horizon
Telescope
.env
APP_URL="https://admin.mysite.com"
ASSET_URL="https://admin.mysite.com"
APP_DOMAIN=mysite.com
# using AWS elasticache
SESSION_DRIVER=redis
SESSION_LIFETIME=120
SESSION_DOMAIN=mysite.com
session.php
'driver' => env('SESSION_DRIVER', 'database'),
'lifetime' => env('SESSION_LIFETIME', 120),
'expire_on_close' => false,
'encrypt' => false,
'files' => storage_path('framework/sessions'),
'connection' => env('SESSION_CONNECTION'),
'table' => 'sessions',
'store' => env('SESSION_STORE'),
'lottery' => [2, 100],
'cookie' => env(
'SESSION_COOKIE',
Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
),
'path' => '/',
'domain' => env('SESSION_DOMAIN'),
'secure' => env('SESSION_SECURE_COOKIE'),
'http_only' => true,
'same_site' => 'lax',
<meta name="csrf_token" value="{{ csrf_token() }}"/> is set on my layouts
I tried downgrading livewire as it was updated a few weeks ago, but this didn't change anything.
I tried leaving SESSION_DOMAIN empty. No luck
I tried setting SESSION_SECURE_COOKIE to true.
I verified that the timezone in app.php is the same as on the server.
I add debugbar installed but only used on local. I removed it completely to be sure.
I tested the Laravel Caffeine package, and dropped the drip to 30 seconds, but it didn't drip at all outside of my local...
I have ran php artisan optimize:clear and php artisan octane:reload after all changes.
I implemented this temporary unsecure workaround given the console indicates that livewire/update returns 419
class VerifyCsrfToken extends Middleware {
protected $except = [
'livewire/*',
];
}
This helps me pass the login form more easily but I still get kicked out after a minute or so.
Finally, expending on my particular setup, one of the latest changes we implemented was the separate subdomains for the admin area and the API, so I wonder if something is wrong there. We have set up 2 extra environment variables CMS_SUBDOMAIN_PREFIX=admin and API_SUBDOMAIN_PREFIX=api and have the following config in our RouteServiceProvider
public function boot()
{
$this->configureRateLimiting();
$this->routes(function () {
Route::middleware('api')
->domain(env('API_SUBDOMAIN_PREFIX', 'api') . '.' . config('app.domain', null))
->prefix('v1')
->name('api.v1.')
->group(base_path('routes/api.php'));
Route::middleware('web')
->domain(env('CMS_SUBDOMAIN_PREFIX', 'admin') . '.' . config('app.domain', null))
->group(base_path('routes/web.php'));
Route::middleware('web')
->prefix('/socialite')
->name('socialite.')
->group(base_path('routes/socialite.php'));
});
}
Any suggestion is more than welcome! :)