Fix Laravel Session Not Working — Login Immediately Logs Out (2025)
🔐 Fix “Session Not Working — User logs in then immediately logs out” (Laravel, 2025) Error (symptom): User logs in but is immediately logged out / session not persisting This problem usually comes from cookie, session driver, domain, or server configuration issues. Let’s fix it step-by-step. 🔍 Why this happens (common causes) Wrong SESSION_DOMAIN — cookie domain doesn’t match your app domain (subdomain vs root domain). Session driver misconfigured (file vs database vs redis) or driver failing. Secure cookie / HTTPS mismatch — cookie set as secure but site served over HTTP (or vice-versa). Storage permission issues (when using file driver): Laravel can’t write session files. Multiple servers/load balancer without sticky sessions or central session store. Browser blocking cookies (SameSite policy or third-party cookie blocking). APP_URL mismatch (scheme / domain differs from what cookie expects). Expired sessions or very short SESSION_LIFETIME. 🛠 Step-by-step fixes (do these in order) 1) .env — set sensible session settings Example .env recommended values: APP_URL=https://yourdomain.com SESSION_DRIVER=file # or database, redis, etc. SESSION_DOMAIN=.yourdomain.com # note leading dot for subdomains (or null for localhost) SESSION_SECURE_COOKIE=true # true if using HTTPS, false for HTTP (use HTTPS in production) SESSION_LIFETIME=120 # minutes SESSION_SAME_SITE=lax # 'lax' is default; use 'none' only if cross-site cookies required (with secure=true) Notes: For local development (localhost) use SESSION_DOMAIN=null or leave empty. For subdomain support (eg. app.yourdomain.com + www.yourdomain.com), set SESSION_DOMAIN=.yourdomain.com (leading dot). If you use SESSION_SECURE_COOKIE=true, ensure APP_URL uses https:// and your site is served via HTTPS. 2) Clear Laravel caches After updating .env always clear config/cache so Laravel picks up changes: php artisan config:clear php artisan cache:clear php artisan route:clear php artisan view:clear (Optionally restart PHP-FPM / workers after this.) 3) Check session storage & permissions (when using file driver) If using file driver (default), sessions are stored in storage/framework/sessions. Ensure Laravel can write there: sudo chown -R www-data:www-data storage bootstrap/cache sudo chmod -R 775 storage bootstrap/cache (Replace www-data with your web server user.) 4) If using database driver — create session table If SESSION_DRIVER=database, create the table: php artisan session:table php artisan migrate Confirm sessions are being written to the table. 5) If using redis/memcached — check connection If SESSION_DRIVER=redis or memcached, verify connections in config/database.php and config/cache.php. Test that Redis is reachable and credentials are correct. 6) Inspect browser cookies (quick debug) Open DevTools → Application (Chrome) → Cookies: Look for cookie name (default laravel_session). Check Domain, Path, Secure, SameSite, Expires. If cookie is missing, the app didn’t set it (server issue). If cookie is present but login still fails, the server likely cannot read/validate session. 7) APP_URL, reverse proxies & HTTPS Ensure APP_URL matches the public URL (including scheme). If behind a proxy/load balancer, configure trusted proxies (e.g., fideloper/proxy or built-in handling) so Laravel knows requests are HTTPS. Otherwise cookies may be marked insecure or redirect incorrectly. 8) Multiple servers / load balancer In a multi-server setup, use a central session store (Redis or database) or enable sticky sessions at the load balancer. File sessions will not work if requests go to different servers. 🔎 Quick troubleshooting checklist .env values (SESSION_DOMAIN, SESSION_SECURE_COOKIE, APP_URL) correct php artisan config:clear run after .env changes Cookie appears in browser and domain/path match site storage/framework/sessions writable (for file driver) If database driver — sessions table exists & receives rows If using redis/memcached — connection is alive No conflicting middleware or custom guard expiring sessions If deployed behind proxy — trusted proxies configured 🎯 Pro tips (best practices) Use SESSION_DRIVER=redis (or database) in production for reliability across multiple servers. Always use HTTPS in production and set SESSION_SECURE_COOKIE=true. For subdomains, use SESSION_DOMAIN=.yourdomain.com and SESSION_SAME_SITE=None (only if needed) with secure cookie. Use php artisan serve only for local testing — real webserver behavior may differ. Monitor session writes (logs or DB) to confirm sessions are created. Back