Laravel Session Management: A Quick Guide to Storing User Data

Published on November 22, 2025
Laravel Sessions SessionManagement StateManagement PHP

What are Laravel Sessions?

Sessions provide a way to store information about users across multiple requests. Laravel sessions are secure, driver-based, and easy to use for maintaining state in your web applications.

Common Session Use Cases:

  • User authentication state
  • Shopping cart contents
  • Form data across multi-step processes
  • User preferences and settings
  • Temporary notification messages

Session Configuration

Session Configuration File

<?php
// config/session.php

return [
    // Default session driver
    'driver' => env('SESSION_DRIVER', 'file'),

    // Session lifetime (minutes)
    'lifetime' => env('SESSION_LIFETIME', 120),
    'expire_on_close' => false,

    // Session encryption
    'encrypt' => false,

    // Session file location (for file driver)
    'files' => storage_path('framework/sessions'),

    // Database connection (for database driver)
    'connection' => env('SESSION_CONNECTION'),
    'table' => 'sessions',

    // Cache store (for cache driver)
    'store' => env('SESSION_STORE'),

    // Sweeping lottery (garbage collection)
    'lottery' => [2, 100],

    // Cookie settings
    'cookie' => env('SESSION_COOKIE', 'laravel_session'),
    'path' => '/',
    'domain' => env('SESSION_DOMAIN'),
    'secure' => env('SESSION_SECURE_COOKIE'),
    'http_only' => true,
    'same_site' => 'lax',
];

Session Drivers

Available Session Drivers

1. File Driver (Default)

// .env
SESSION_DRIVER=file

// Sessions stored in: storage/framework/sessions/

2. Cookie Driver

SESSION_DRIVER=cookie
// Limited to 4KB, encrypted automatically

3. Database Driver

// .env
SESSION_DRIVER=database
SESSION_CONNECTION=mysql

// Create sessions table
php artisan session:table
php artisan migrate

4. Redis Driver

// .env
SESSION_DRIVER=redis
SESSION_CONNECTION=session

// config/database.php
'redis' => [
    'session' => [
        'host' => env('REDIS_HOST', '127.0.0.1'),
        'password' => env('REDIS_PASSWORD'),
        'port' => env('REDIS_PORT', 6379),
        'database' => env('REDIS_SESSION_DB', 1),
    ],
],

5. Memcached Driver

// .env
SESSION_DRIVER=memcached

6. Array Driver (Testing)

// .env
SESSION_DRIVER=array
// Volatile, only for testing

Basic Session Operations

Storing Session Data

Using the Session Facade
<?php
// app/Http/Controllers/UserController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;

class UserController extends Controller
{
    public function storePreferences(Request $request)
    {
        // Store single value
        Session::put('theme', $request->theme);
        Session::put('language', $request->language);
        
        // Store multiple values
        Session::put([
            'notifications_enabled' => $request->has('notifications'),
            'timezone' => $request->timezone,
            'results_per_page' => $request->results_per_page,
        ]);
        
        return redirect()->back()->with('success', 'Preferences saved!');
    }
    
    public function addToCart(Request $request)
    {
        $productId = $request->product_id;
        $quantity = $request->quantity;
        
        // Push to array session value
        Session::push('cart.items', [
            'product_id' => $productId,
            'quantity' => $quantity,
            'added_at' => now(),
        ]);
        
        // Increment cart count
        Session::increment('cart.total_items', $quantity);
        
        return response()->json([
            'message' => 'Item added to cart',
            'cart_count' => Session::get('cart.total_items', 0)
        ]);
    }
}
Using the Request Instance
public function updateProfile(Request $request)
{
    // Store using request instance
    $request->session()->put('user_profile_in_progress', true);
    $request->session()->put('profile_data', $request->except('_token'));
    
    return redirect()->route('profile.step2');
}
Using Global session() Helper
public function setUserTimezone(Request $request)
{
    // Using global helper
    session(['timezone' => $request->timezone]);
    session(['last_timezone_update' => now()]);
    
    return response()->json(['success' => true]);
}

Retrieving Session Data

Basic Retrieval Methods
public function showDashboard(Request $request)
{
    // Get session value with default
    $theme = Session::get('theme', 'light');
    $language = session('language', 'en');
    
    // Check if session value exists
    if (Session::has('user_preferences')) {
        $preferences = Session::get('user_preferences');
    }
    
    // Get all session data
    $allSessionData = Session::all();
    
    // Get and remove session value
    $temporaryData = Session::pull('temp_data');
    
    return view('dashboard', compact('theme', 'language', 'preferences'));
}
Working with Arrays in Session
public function manageCart(Request $request)
{
    // Get cart items or initialize empty array
    $cartItems = Session::get('cart.items', []);
    
    // Check if item exists in cart
    $itemIndex = array_search(
        $request->product_id, 
        array_column($cartItems, 'product_id')
    );
    
    if ($itemIndex !== false) {
        // Update existing item quantity
        $cartItems[$itemIndex]['quantity'] += $request->quantity;
        Session::put('cart.items', $cartItems);
    }
    
    // Calculate total
    $total = array_sum(array_column($cartItems, 'quantity'));
    Session::put('cart.total_items', $total);
    
    return view('cart', compact('cartItems', 'total'));
}

Removing Session Data

Removing Session Values
public function clearPreferences(Request $request)
{
    // Remove single value
    Session::forget('theme');
    Session::forget('language');
    
    // Remove multiple values
    Session::forget([
        'notifications_enabled',
        'timezone',
        'results_per_page'
    ]);
    
    // Remove all session data
    // Session::flush(); // Use carefully!
    
    return redirect()->back()->with('info', 'Preferences cleared');
}

public function removeFromCart(Request $request)
{
    $productId = $request->product_id;
    $cartItems = Session::get('cart.items', []);
    
    // Filter out the item to remove
    $cartItems = array_filter($cartItems, function($item) use ($productId) {
        return $item['product_id'] != $productId;
    });
    
    // Re-index array
    $cartItems = array_values($cartItems);
    
    Session::put('cart.items', $cartItems);
    
    // Update total
    $total = array_sum(array_column($cartItems, 'quantity'));
    Session::put('cart.total_items', $total);
    
    return response()->json([
        'success' => true,
        'cart_count' => $total
    ]);
}

Flash Data (Temporary Session Data)

What is Flash Data?

Flash data is session data that is available only for the next request. It's automatically cleared after being accessed.

Using Flash Data

<?php
// app/Http/Controllers/AuthController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class AuthController extends Controller
{
    public function login(Request $request)
    {
        $credentials = $request->validate([
            'email' => 'required|email',
            'password' => 'required',
        ]);
        
        if (Auth::attempt($credentials)) {
            // Flash success message
            Session::flash('success', 'Welcome back!');
            
            // Flash user-specific data
            Session::flash('login_time', now());
            Session::flash('user_ip', $request->ip());
            
            return redirect()->intended('dashboard');
        }
        
        // Flash error message
        Session::flash('error', 'Invalid credentials. Please try again.');
        
        return back()->withInput();
    }
    
    public function register(Request $request)
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|email|unique:users',
            'password' => 'required|min:8|confirmed',
        ]);
        
        $user = User::create($validated);
        Auth::login($user);
        
        // Flash multiple values
        Session::flash('welcome_message', true);
        Session::flash('user_name', $user->name);
        
        return redirect()->route('onboarding.start');
    }
}

Reflashing and Keeping Flash Data

public function multiStepForm(Request $request)
{
    if ($request->isMethod('POST')) {
        // Store form data in session
        Session::put('form_data.step1', $request->except('_token'));
        
        // Flash validation message
        Session::flash('message', 'Step 1 completed!');
        
        // Keep flash data for next request
        Session::reflash();
        
        return redirect()->route('form.step2');
    }
    
    return view('form.step1');
}

public function step2Form(Request $request)
{
    // Flash data from step1 is still available
    $step1Data = Session::get('form_data.step1');
    
    if ($request->isMethod('POST')) {
        Session::put('form_data.step2', $request->except('_token'));
        
        // Keep specific flash data
        Session::keep(['message', 'user_name']);
        
        return redirect()->route('form.review');
    }
    
    return view('form.step2', compact('step1Data'));
}

Advanced Session Management

Custom Session Drivers

Creating a Custom Session Driver
<?php
// app/Extensions/MongoSessionHandler.php

namespace App\Extensions;

use Illuminate\Contracts\Session\Session;
use MongoDB\Client;

class MongoSessionHandler implements \SessionHandlerInterface
{
    protected $collection;
    protected $lifetime;

    public function __construct()
    {
        $client = new Client(env('MONGO_URI'));
        $this->collection = $client->selectDatabase('sessions')
                                 ->selectCollection('sessions');
        $this->lifetime = config('session.lifetime') * 60;
    }

    public function open($savePath, $sessionName): bool
    {
        return true;
    }

    public function close(): bool
    {
        return true;
    }

    public function read($sessionId): string
    {
        $session = $this->collection->findOne([
            'session_id' => $sessionId,
            'expires_at' => ['$gt' => time()]
        ]);

        return $session ? $session['data'] : '';
    }

    public function write($sessionId, $data): bool
    {
        $this->collection->updateOne(
            ['session_id' => $sessionId],
            [
                '$set' => [
                    'data' => $data,
                    'expires_at' => time() + $this->lifetime,
                    'last_activity' => time()
                ]
            ],
            ['upsert' => true]
        );

        return true;
    }

    public function destroy($sessionId): bool
    {
        $this->collection->deleteOne(['session_id' => $sessionId]);
        return true;
    }

    public function gc($lifetime): int
    {
        return $this->collection->deleteMany([
            'expires_at' => ['$lt' => time()]
        ])->getDeletedCount();
    }
}
Registering Custom Driver
<?php
// app/Providers/AppServiceProvider.php

namespace App\Providers;

use Illuminate\Support\Facades\Session;
use Illuminate\Support\ServiceProvider;
use App\Extensions\MongoSessionHandler;

class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        Session::extend('mongo', function ($app) {
            return new MongoSessionHandler;
        });
    }
}

Session Events

Listening to Session Events
<?php
// app/Providers/EventServiceProvider.php

namespace App\Providers;

use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;

class EventServiceProvider extends ServiceProvider
{
    protected $listen = [
        // Session started event
        \Illuminate\Session\Events\SessionStarted::class => [
            \App\Listeners\LogSessionStart::class,
        ],
        
        // Session regenerated event
        \Illuminate\Session\Events\SessionRegenerated::class => [
            \App\Listeners\UpdateSessionTimestamp::class,
        ],
    ];
}
Custom Session Event Listeners
<?php
// app/Listeners/LogSessionStart.php

namespace App\Listeners;

use Illuminate\Session\Events\SessionStarted;
use Illuminate\Support\Facades\Log;

class LogSessionStart
{
    public function handle(SessionStarted $event): void
    {
        Log::info('Session started', [
            'session_id' => $event->session->getId(),
            'user_id' => auth()->id() ?? 'guest',
            'ip_address' => request()->ip(),
        ]);
    }
}

// app/Listeners/UpdateSessionTimestamp.php

namespace App\Listeners;

use Illuminate\Session\Events\SessionRegenerated;
use Illuminate\Support\Facades\DB;

class UpdateSessionTimestamp
{
    public function handle(SessionRegenerated $event): void
    {
        if (auth()->check()) {
            // Update user's last activity
            DB::table('users')
                ->where('id', auth()->id())
                ->update(['last_session_activity' => now()]);
        }
    }
}

Real-World Session Examples

Shopping Cart Implementation

<?php
// app/Http/Controllers/CartController.php

namespace App\Http\Controllers;

use App\Models\Product;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;

class CartController extends Controller
{
    public function showCart()
    {
        $cartItems = Session::get('cart.items', []);
        $total = Session::get('cart.total', 0);
        $itemCount = Session::get('cart.item_count', 0);
        
        // Get product details for cart items
        $productIds = array_column($cartItems, 'product_id');
        $products = Product::whereIn('id', $productIds)->get()->keyBy('id');
        
        return view('cart.show', compact('cartItems', 'products', 'total', 'itemCount'));
    }
    
    public function addToCart(Request $request)
    {
        $request->validate([
            'product_id' => 'required|exists:products,id',
            'quantity' => 'required|integer|min:1',
        ]);
        
        $product = Product::findOrFail($request->product_id);
        $cartItems = Session::get('cart.items', []);
        
        // Check if product already in cart
        $existingIndex = $this->findCartItemIndex($cartItems, $product->id);
        
        if ($existingIndex !== false) {
            // Update existing item
            $cartItems[$existingIndex]['quantity'] += $request->quantity;
        } else {
            // Add new item
            $cartItems[] = [
                'product_id' => $product->id,
                'quantity' => $request->quantity,
                'price' => $product->price,
                'added_at' => now()->toDateTimeString(),
            ];
        }
        
        // Update session
        Session::put('cart.items', $cartItems);
        $this->updateCartTotals();
        
        return response()->json([
            'success' => true,
            'cart_count' => Session::get('cart.item_count', 0),
            'message' => 'Product added to cart'
        ]);
    }
    
    public function updateCart(Request $request)
    {
        $cartItems = Session::get('cart.items', []);
        
        foreach ($request->quantities as $productId => $quantity) {
            $index = $this->findCartItemIndex($cartItems, $productId);
            
            if ($index !== false) {
                if ($quantity <= 0) {
                    // Remove item if quantity is 0 or less
                    unset($cartItems[$index]);
                } else {
                    // Update quantity
                    $cartItems[$index]['quantity'] = $quantity;
                }
            }
        }
        
        // Re-index array
        $cartItems = array_values($cartItems);
        
        Session::put('cart.items', $cartItems);
        $this->updateCartTotals();
        
        Session::flash('success', 'Cart updated successfully');
        return redirect()->route('cart.show');
    }
    
    public function clearCart()
    {
        Session::forget('cart');
        Session::flash('info', 'Cart cleared successfully');
        
        return redirect()->route('cart.show');
    }
    
    protected function findCartItemIndex($cartItems, $productId)
    {
        foreach ($cartItems as $index => $item) {
            if ($item['product_id'] == $productId) {
                return $index;
            }
        }
        
        return false;
    }
    
    protected function updateCartTotals()
    {
        $cartItems = Session::get('cart.items', []);
        
        $total = 0;
        $itemCount = 0;
        
        foreach ($cartItems as $item) {
            $total += $item['quantity'] * $item['price'];
            $itemCount += $item['quantity'];
        }
        
        Session::put('cart.total', $total);
        Session::put('cart.item_count', $itemCount);
    }
}

Multi-step Form Wizard

<?php
// app/Http/Controllers/RegistrationController.php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Session;

class RegistrationController extends Controller
{
    public function showStep1()
    {
        $data = Session::get('registration.data', []);
        return view('registration.step1', compact('data'));
    }
    
    public function postStep1(Request $request)
    {
        $validated = $request->validate([
            'email' => 'required|email|unique:users',
            'password' => 'required|min:8|confirmed',
        ]);
        
        // Store in session
        Session::put('registration.data.step1', $validated);
        Session::put('registration.current_step', 2);
        
        return redirect()->route('registration.step2');
    }
    
    public function showStep2()
    {
        $this->ensureStepAccess(2);
        $data = Session::get('registration.data', []);
        
        return view('registration.step2', compact('data'));
    }
    
    public function postStep2(Request $request)
    {
        $this->ensureStepAccess(2);
        
        $validated = $request->validate([
            'first_name' => 'required|string|max:255',
            'last_name' => 'required|string|max:255',
            'phone' => 'required|string|max:20',
        ]);
        
        Session::put('registration.data.step2', $validated);
        Session::put('registration.current_step', 3);
        
        return redirect()->route('registration.step3');
    }
    
    public function showStep3()
    {
        $this->ensureStepAccess(3);
        $data = Session::get('registration.data', []);
        
        return view('registration.step3', compact('data'));
    }
    
    public function postStep3(Request $request)
    {
        $this->ensureStepAccess(3);
        
        $validated = $request->validate([
            'company_name' => 'nullable|string|max:255',
            'job_title' => 'nullable|string|max:255',
            'newsletter' => 'boolean',
        ]);
        
        Session::put('registration.data.step3', $validated);
        
        return redirect()->route('registration.review');
    }
    
    public function showReview()
    {
        $data = Session::get('registration.data', []);
        
        if (empty($data['step1']) || empty($data['step2'])) {
            return redirect()->route('registration.step1')
                           ->with('error', 'Please complete all required steps');
        }
        
        return view('registration.review', compact('data'));
    }
    
    public function completeRegistration()
    {
        $data = Session::get('registration.data', []);
        
        // Validate all required data is present
        if (empty($data['step1']) || empty($data['step2'])) {
            return redirect()->route('registration.step1')
                           ->with('error', 'Please complete all required steps');
        }
        
        // Create user
        $user = User::create([
            'email' => $data['step1']['email'],
            'password' => Hash::make($data['step1']['password']),
            'first_name' => $data['step2']['first_name'],
            'last_name' => $data['step2']['last_name'],
            'phone' => $data['step2']['phone'],
            'company_name' => $data['step3']['company_name'] ?? null,
            'job_title' => $data['step3']['job_title'] ?? null,
            'newsletter_opt_in' => $data['step3']['newsletter'] ?? false,
        ]);
        
        // Clear registration session
        Session::forget('registration');
        
        // Flash success message
        Session::flash('success', 'Registration completed successfully!');
        
        auth()->login($user);
        
        return redirect()->route('dashboard');
    }
    
    protected function ensureStepAccess($step)
    {
        $currentStep = Session::get('registration.current_step', 1);
        
        if ($step > $currentStep) {
            return redirect()->route("registration.step{$currentStep}")
                           ->with('error', 'Please complete previous steps first');
        }
    }
}

Session Security Best Practices

Secure Session Configuration

// config/session.php

return [
    'driver' => env('SESSION_DRIVER', 'database'),
    'lifetime' => env('SESSION_LIFETIME', 120),
    'expire_on_close' => false,
    'encrypt' => env('SESSION_ENCRYPT', false),
    'cookie' => env('SESSION_COOKIE', 'laravel_session'),
    
    // Security settings
    'secure' => env('SESSION_SECURE_COOKIE', true),
    'http_only' => true,
    'same_site' => 'lax', // or 'strict' for better security
];

Session Regeneration

<?php
// app/Http/Middleware/ValidateSessions.php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class ValidateSessions
{
    public function handle(Request $request, Closure $next)
    {
        // Regenerate session ID periodically for security
        if ($this->shouldRegenerateSession()) {
            $request->session()->regenerate();
        }
        
        // Validate user session
        if (Auth::check() && $this->sessionExpired($request)) {
            Auth::logout();
            $request->session()->invalidate();
            $request->session()->regenerateToken();
            
            return redirect()->route('login')
                           ->with('error', 'Session expired. Please log in again.');
        }
        
        return $next($request);
    }
    
    protected function shouldRegenerateSession(): bool
    {
        // Regenerate every 100 requests or 30 minutes
        $lastRegeneration = session('last_session_regeneration', 0);
        return (time() - $lastRegeneration > 1800) || 
               (session('request_count', 0) >= 100);
    }
    
    protected function sessionExpired(Request $request): bool
    {
        $lastActivity = $request->session()->get('last_activity');
        
        if (!$lastActivity) {
            return false;
        }
        
        return time() - $lastActivity > config('session.lifetime') * 60;
    }
}

Testing Session Management

Session Testing Examples

<?php
// tests/Feature/SessionTest.php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;

class SessionTest extends TestCase
{
    use RefreshDatabase;

    public function test_session_data_storage_and_retrieval()
    {
        // Set session data
        $this->withSession(['theme' => 'dark', 'language' => 'fr'])
             ->get('/dashboard');
        
        // Verify session data persists
        $this->get('/preferences')
             ->assertSessionHas('theme', 'dark')
             ->assertSessionHas('language', 'fr');
    }
    
    public function test_flash_data_availability()
    {
        // Set flash data
        $response = $this->post('/login', [
            'email' => 'user@example.com',
            'password' => 'password'
        ]);
        
        // Flash data should be available for next request
        $response->assertSessionHas('success');
        
        // But not after subsequent requests
        $this->get('/dashboard')
             ->assertSessionMissing('success');
    }
    
    public function test_shopping_cart_functionality()
    {
        $user = \App\Models\User::factory()->create();
        
        $this->actingAs($user)
             ->post('/cart/add', [
                 'product_id' => 1,
                 'quantity' => 2
             ])
             ->assertSessionHas('cart.items')
             ->assertSessionHas('cart.total_items', 2);
        
        // Verify cart contents
        $this->get('/cart')
             ->assertSee('Shopping Cart')
             ->assertSessionHas('cart.total_items', 2);
    }
    
    public function test_session_clearing()
    {
        $this->withSession([
            'preferences' => ['theme' => 'dark'],
            'cart' => ['items' => []]
        ]);
        
        $this->post('/session/clear')
             ->assertSessionMissing('preferences')
             ->assertSessionMissing('cart');
    }
    
    public function test_multi_step_form_session_persistence()
    {
        $response = $this->post('/registration/step1', [
            'email' => 'test@example.com',
            'password' => 'password123',
            'password_confirmation' => 'password123'
        ]);
        
        $response->assertSessionHas('registration.data.step1')
                 ->assertRedirect('/registration/step2');
        
        // Continue to step 2 with session data
        $this->get('/registration/step2')
             ->assertOk();
    }
}

// tests/Unit/SessionUnitTest.php

class SessionUnitTest extends TestCase
{
    public function test_session_helper_functions()
    {
        // Test session helper
        session(['test_key' => 'test_value']);
        $this->assertEquals('test_value', session('test_key'));
        
        // Test session exists
        $this->assertTrue(session()->has('test_key'));
        
        // Test session forget
        session()->forget('test_key');
        $this->assertFalse(session()->has('test_key'));
    }
    
    public function test_session_flash_data()
    {
        session()->flash('message', 'Hello World');
        
        // Flash data should exist
        $this->assertTrue(session()->has('message'));
        $this->assertEquals('Hello World', session('message'));
        
        // Simulate next request
        session()->ageFlashData();
        
        // Flash data should be gone
        $this->assertFalse(session()->has('message'));
    }
}

Performance Optimization

Session Driver Selection

// For high-traffic applications, use Redis or database
SESSION_DRIVER=redis

// For development, use file or array
SESSION_DRIVER=file

Session Data Optimization

public function storeUserPreferences(Request $request)
{
    // Store only necessary data
    $preferences = [
        'theme' => $request->theme,
        'language' => $request->language,
        // Don't store large objects in session
    ];
    
    Session::put('preferences', $preferences);
    
    // For large data, consider database storage
    if (auth()->check()) {
        auth()->user()->update(['preferences' => $preferences]);
    }
}

Common Interview Questions & Answers

1. What's the difference between session()->put() and session()->flash()?

put() stores data for the entire session duration, while flash() stores data only for the next request. Flash data is automatically cleared after being accessed.

2. When should you use database session driver vs file driver?

Use database driver for load-balanced applications or when you need to share sessions across multiple servers. Use file driver for single-server applications or development environments.

3. How do you secure Laravel sessions?

Use HTTPS, set secure cookies, enable http_only flags, use same_site cookies, regenerate session IDs periodically, and set appropriate session lifetimes.

4. What's the maximum size of session data?

It depends on the driver: file/system limits for file driver, 4KB for cookie driver, database column limits for database driver. Keep session data minimal for best performance.

5. How do you handle sessions in API development?

APIs are typically stateless and don't use sessions. Use token-based authentication (JWT, Sanctum) instead of session-based authentication for APIs.

6. What happens when session data becomes too large?

Performance degrades. For file driver, disk I/O increases. For database driver, queries slow down. Always keep session data minimal and consider storing large data in cache or database.

Troubleshooting Common Issues

Session Not Persisting

// Check session configuration
// Ensure same_site is not too restrictive
'same_site' => 'lax', // Instead of 'strict'

// Check domain configuration
'domain' => '.yourdomain.com', // For subdomains

// Verify secure cookie setting in production
'secure' => true,

Session Data Lost

// Regenerate session ID properly
$request->session()->regenerate(); // Preserves data
$request->session()->invalidate(); // Clears data

// Handle session timeouts
public function checkSession(Request $request)
{
    if ($request->session()->has('last_activity')) {
        $timeout = config('session.lifetime') * 60;
        if (time() - session('last_activity') > $timeout) {
            auth()->logout();
            $request->session()->invalidate();
            return redirect('/login');
        }
    }
    
    session(['last_activity' => time()]);
}

You’ve now mastered Laravel session management and can effectively manage user state across requests! In our next post, we’ll dive into Laravel Service Container: The Heart of Laravel Explained Simply to help you understand how Laravel resolves dependencies and manages class bindings behind the scenes.