Fix Laravel Session Not Working — Login Immediately Logs Out (2025)

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