Skip to content
beginner Phase 2 · HTTP Deep Dive

Cookies and Sessions: State Management on the Web

Understand cookies vs sessions, PHP session handling, cookie security, SameSite attributes, and how Magento manages sessions.

45m
0 problems
Topic Progress 0%

Cookies vs Sessions

Cookies

Cookies are small pieces of data stored on the client (browser). They are sent with every request to the server.

Feature Cookie Session
Storage Client (browser) Server (file/database/Redis)
Size Limit 4KB per cookie No practical limit
Lifetime Configurable expiration Ends when browser closes (default)
Security Visible to client Only session ID is visible
Performance Sent with every request Only session ID sent
Use Case Preferences, tracking, auth tokens Shopping cart, login state, user data

Setting Cookies in PHP

<?php
// Basic cookie
setcookie(
    'user_preference',           // name
    'dark_mode',                 // value
    time() + (86400 * 30),       // expiry: 30 days from now
    '/',                         // path: available on entire site
    'magento-store.com',         // domain
    true,                        // secure: HTTPS only
    true                         // httponly: no JavaScript access
);

// Modern cookie attributes (PHP 7.3+)
setcookie(
    'session_id',
    $sessionId,
    [
        'expires' => time() + 3600,
        'path' => '/',
        'domain' => '.magento-store.com',
        'secure' => true,
        'httponly' => true,
        'samesite' => 'Lax'  // CSRF protection
    ]
);

// Read a cookie
$preference = $_COOKIE['user_preference'] ?? 'light_mode';

// Delete a cookie
setcookie('user_preference', '', [
    'expires' => time() - 3600,
    'path' => '/',
    'domain' => 'magento-store.com'
]);

SameSite Attribute

Value Behavior
Strict Cookie only sent for same-site requests (most secure)
Lax Cookie sent for top-level navigation and GET requests (default)
None Cookie sent for all requests (requires Secure flag)
# SameSite=Strict (most secure)
Set-Cookie: session=abc123; SameSite=Strict; Secure; HttpOnly

# SameSite=Lax (balanced - default in modern browsers)
Set-Cookie: session=abc123; SameSite=Lax; Secure; HttpOnly

# SameSite=None (cross-site, requires Secure)
Set-Cookie: session=abc123; SameSite=None; Secure; HttpOnly

PHP Sessions

<?php
// Start session - must be called before any output
session_start();

// Session data is stored on the server
// Only the session ID (PHPSESSID) is stored in a cookie

// Set session data
$_SESSION['user_id'] = 123;
$_SESSION['user_name'] = 'John Doe';
$_SESSION['cart'] = [
    ['product_id' => 1, 'qty' => 2],
    ['product_id' => 5, 'qty' => 1]
];

// Read session data
$userId = $_SESSION['user_id'] ?? null;
$cartCount = count($_SESSION['cart'] ?? []);

// Delete specific session data
unset($_SESSION['user_name']);

// Destroy entire session (logout)
session_destroy();

Session Configuration

<?php
// Configure session before session_start()
session_name('MAGENTO_SESSION'); // Custom session name

ini_set('session.cookie_httponly', 1);   // No JavaScript access
ini_set('session.cookie_secure', 1);    // HTTPS only
ini_set('session.cookie_samesite', 'Lax'); // CSRF protection
ini_set('session.use_strict_mode', 1);   // Reject uninitialized sessions
ini_set('session.gc_maxlifetime', 14400); // 4 hours

// Custom session save handler
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://127.0.0.1:6379?database=1');

session_start();

Key Takeaway

Cookies store data on the client, sessions store data on the server. Use cookies for small, persistent preferences. Use sessions for sensitive, temporary data like authentication state and shopping carts.

Session Security and Management

Session Security Threats

Threat Description Prevention
Session Hijacking Attacker steals session ID HttpOnly, Secure, SameSite cookies
Session Fixation Attacker sets known session ID Regenerate ID after login
CSRF Attacker tricks user into actions SameSite cookies, CSRF tokens
Session Data Exposure Server-side data leaks Don't store sensitive data in sessions

Session Fixation Prevention

<?php
// After successful login, regenerate session ID
function loginUser(string $email, string $password): bool
{
    $user = authenticateUser($email, $password);
    
    if ($user) {
        // IMPORTANT: Regenerate session ID to prevent session fixation
        session_regenerate_id(true); // Delete old session file
        
        // Store user data in session
        $_SESSION['user_id'] = $user->getId();
        $_SESSION['user_email'] = $user->getEmail();
        $_SESSION['logged_in'] = true;
        $_SESSION['login_time'] = time();
        
        return true;
    }
    
    return false;
}

// Check session timeout (idle timeout)
function isSessionExpired(int $timeoutSeconds = 1800): bool
{
    if (!isset($_SESSION['last_activity'])) {
        $_SESSION['last_activity'] = time();
        return false;
    }
    
    if (time() - $_SESSION['last_activity'] > $timeoutSeconds) {
        // Session timed out
        session_unset();
        session_destroy();
        return true;
    }
    
    $_SESSION['last_activity'] = time();
    return false;
}

Secure Session Configuration

<?php
// Complete secure session setup
function configureSecureSession(): void
{
    // Set session name (don't use default PHPSESSID)
    session_name('MAGE_SESS');
    
    // Security settings
    ini_set('session.use_strict_mode', 1);     // Reject uninitialized sessions
    ini_set('session.use_only_cookies', 1);    // No session ID in URL
    ini_set('session.use_trans_sid', 0);       // Don't add session ID to URLs
    
    // Cookie settings
    ini_set('session.cookie_httponly', 1);      // No JavaScript access
    ini_set('session.cookie_secure', 1);       // HTTPS only
    ini_set('session.cookie_samesite', 'Lax'); // CSRF protection
    ini_set('session.cookie_path', '/');
    ini_set('session.cookie_domain', '.magento-store.com');
    
    // Session lifetime
    ini_set('session.gc_maxlifetime', 14400);  // 4 hours garbage collection
    ini_set('session.cookie_lifetime', 0);     // Browser session (cookie expires when browser closes)
    
    // Use Redis for session storage
    ini_set('session.save_handler', 'redis');
    ini_set('session.save_path', 'tcp://127.0.0.1:6379?database=1&prefix=sess_');
}

CSRF Protection with Sessions

<?php
// Generate CSRF token
defineCSRFToken(): string
{
    if (empty($_SESSION['csrf_token'])) {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
    }
    return $_SESSION['csrf_token'];
}

// Validate CSRF token
function validateCSRFToken(string $token): bool
{
    return isset($_SESSION['csrf_token']) 
        && hash_equals($_SESSION['csrf_token'], $token);
}

// In HTML form:
// <input type="hidden" name="csrf_token" value="<?= csrfToken() ?>">

// In form handler:
if (!validateCSRFToken($_POST['csrf_token'] ?? '')) {
    http_response_code(403);
    echo json_encode(['error' => 'Invalid CSRF token']);
    exit;
}

Magento Session Handling

Magento Session Architecture

Magento uses sessions extensively for:

  • Customer authentication (logged-in state)
  • Shopping cart contents (guest and customer carts)
  • Checkout state (shipping, payment info)
  • Admin authentication (admin panel login)
  • Form key validation (CSRF protection)

Magento Session Configuration

<!-- app/etc/env.php -->
'session' => [
    'save' => 'redis',
    'redis' => [
        'host' => '127.0.0.1',
        'port' => '6379',
        'password' => '',
        'database' => '2',
        'compression_threshold' => '2048',
        'compression_library' => 'gzip',
        'log_level' => '1',
        'max_concurrency' => '6',
        'break_after_frontend' => '5',
        'break_after_adminhtml' => '3',
        'first_lifetime' => '600',
        'bot_first_lifetime' => '60',
        'bot_lifetime' => '7200',
        'disable_locking' => '0',
        'min_lifetime' => '60',
        'max_lifetime' => '14400'
    ]
]

Magento Session Manager

<?php
namespace Magento\Framework\Session;

use Magento\Framework\Session\SaveHandler\Interface as SaveHandlerInterface;

class Manager
{
    private $isSessionStarted = false;
    private $saveHandler;

    public function __construct(SaveHandlerInterface $saveHandler)
    {
        $this->saveHandler = $saveHandler;
    }

    public function start(): void
    {
        if (!$this->isSessionStarted && !session_id()) {
            $this->configureSession();
            session_start();
            $this->isSessionStarted = true;
        }
    }

    private function configureSession(): void
    {
        $cookieParams = [
            'lifetime' => $this->sessionConfig->getCookieLifetime(),
            'path' => $this->sessionConfig->getCookiePath(),
            'domain' => $this->sessionConfig->getCookieDomain(),
            'secure' => $this->sessionConfig->isCookieSecure(),
            'httponly' => $this->sessionConfig->isCookieHttpOnly(),
            'samesite' => $this->sessionConfig->getCookieSameSite()
        ];

        session_set_cookie_params($cookieParams);
        session_name($this->sessionConfig->getName());
    }

    public function getStorage(): \Magento\Framework\Session\Storage
    {
        return $this->storage;
    }
}

Using Magento Sessions in Custom Modules

<?php
namespace Vendor\Module\Helper;

class SessionHelper
{
    private \Magento\Framework\Session\Manager $sessionManager;
    private \Magento\Framework\Session\Storage $sessionStorage;

    public function __construct(
        \Magento\Framework\Session\Manager $sessionManager,
        \Magento\Framework\Session\Storage $sessionStorage
    ) {
        $this->sessionManager = $sessionManager;
        $this->sessionStorage = $sessionStorage;
    }

    public function setWishlistItems(array $items): void
    {
        $this->sessionStorage->setData('wishlist_items', $items);
    }

    public function getWishlistItems(): array
    {
        return $this->sessionStorage->getData('wishlist_items') ?? [];
    }

    public function clearWishlist(): void
    {
        $this->sessionStorage->unsetData('wishlist_items');
    }
}

Session in Magento Checkout

Guest Flow:
1. Add to cart -> Cart stored in session (PHPSESSID cookie)
2. Checkout -> Session linked to quote
3. Order placed -> Cart cleared from session

Customer Flow:
1. Login -> Session linked to customer ID
2. Add to cart -> Cart linked to customer in database
3. Logout -> Session cleared, cart preserved in database

Key Takeaway

Magento uses Redis-backed sessions for performance. Sessions store critical data like cart contents and authentication state. Always use secure session configuration with HttpOnly, Secure, and SameSite cookie attributes.

Quiz

1. What is the main difference between cookies and sessions?

Question 1 options

2. Why should you regenerate the session ID after login?

Question 2 options

3. What does the SameSite=Lax cookie attribute do?

Question 3 options

4. Where does Magento store session data in production?

Question 4 options

5. What PHP function starts a session?

Question 5 options

Flashcards

Question

What is the maximum size of a cookie?

Answer

4KB (4096 bytes) per cookie. For larger data, use sessions which have no practical size limit.

Question

What does session_regenerate_id(true) do?

Answer

Generates a new session ID and deletes the old session file. The 'true' parameter ensures the old session is completely removed, preventing session fixation attacks.

Question

What are the three SameSite cookie attribute values?

Answer

Strict: Cookie only for same-site requests. Lax: Cookie for top-level navigation and GET requests (default). None: Cookie for all requests (requires Secure flag).

Question

How does Magento store sessions in production?

Answer

Redis. Configuration in app/etc/env.php specifies Redis host, port, database, and session lifetime settings. Files are used for development.

Question

What is session fixation?

Answer

An attack where an attacker sets a known session ID before the user logs in, then uses that ID to hijack the session. Prevented by regenerating session ID after login.

Question

What is the PHPSESSID cookie?

Answer

The default name for the PHP session cookie that stores the session ID. The actual session data is stored on the server, not in this cookie.

Question

How do you prevent session data from being accessed via JavaScript?

Answer

Set the HttpOnly flag: session.cookie_httponly = 1 or setcookie('name', 'value', ['httponly' => true]). This prevents document.cookie from accessing the cookie.

Question

What does session_destroy() do?

Answer

Deletes all session data from the server and removes the session cookie from the browser. Used during logout to completely clear the user's session.

Revision Notes

Key Takeaways

  • 1. Cookies store data on the client (browser), sessions store data on the server
  • 2. Maximum cookie size is 4KB; sessions have no practical size limit
  • 3. Always set HttpOnly, Secure, and SameSite flags on cookies
  • 4. Regenerate session ID after login to prevent session fixation
  • 5. Use Redis for session storage in Magento production environments
  • 6. SameSite=Lax is the default and provides CSRF protection
  • 7. session_start() must be called before any output is sent to the browser

Interview Tips

  • Explain the difference between cookies and sessions with examples
  • Know the SameSite attribute values and when to use each
  • Describe session fixation and how to prevent it
  • Explain why Magento uses Redis for sessions
  • Understand the session lifecycle from login to logout

Cheat Sheet

Cookies & Sessions Cheat Sheet

Cookie Attributes:

setcookie('name', 'value', [
    'expires' => time() + 3600,
    'path' => '/',
    'domain' => '.example.com',
    'secure' => true,     // HTTPS only
    'httponly' => true,    // No JavaScript
    'samesite' => 'Lax'   // CSRF protection
]);

SameSite Values:

  • Strict: Same-site only
  • Lax: Top-level navigation allowed (default)
  • None: All requests (requires Secure)

Session Basics:

session_start();           // Start session
$_SESSION['key'] = 'val'; // Set value
$val = $_SESSION['key'];  // Get value
session_regenerate_id(true); // Regenerate ID
session_destroy();         // Destroy session

Magento Sessions:

  • Stored in Redis (production)
  • Used for: cart, authentication, checkout
  • Config in app/etc/env.php