Kodokon kodokon.com

Sesiones y cookies: inicio de sesión y carrito de compra

Recuerda a tus visitantes de página en página: inicio de sesión seguro, un carrito de compra basado en la sesión y cookies debidamente protegidas.

10 min · 3 preguntas

Abrir esta lección en Kodokon

HTTP no recuerda nada: cada petición llega nueva, sin ningún vínculo con la anterior. Las sesiones resuelven este problema: session_start() asocia al visitante con un identificador único, transmitido en una cookie, y un espacio de almacenamiento del lado del servidor accesible mediante $_SESSION. Llama a session_start() justo al principio de cada página pertinente, antes de cualquier salida.

PHP
<?php

declare(strict_types=1);

session_start();

$storedHash = password_hash('secret123', PASSWORD_DEFAULT);
$password = $_POST['password'] ?? '';

if (password_verify($password, $storedHash)) {
    session_regenerate_id(true);
    $_SESSION['user_id'] = 42;
    header('Location: /account.php');
    exit;
}

echo "Invalid credentials.";
login.php: en realidad, el hash proviene de tu base de datos.

Proteger una página se reduce a comprobar la presencia del usuario en la sesión y redirigir en caso contrario. La sesión también sirve como el almacenamiento temporal ideal para un carrito de compra: un array asociativo id de producto => cantidad sobrevive de página en página.

PHP
<?php

declare(strict_types=1);

session_start();

if (!isset($_SESSION['user_id'])) {
    header('Location: /login.php');
    exit;
}

$_SESSION['cart'] ??= [];

$productId = filter_input(
    INPUT_POST,
    'product_id',
    FILTER_VALIDATE_INT
);

if (is_int($productId)) {
    $qty = $_SESSION['cart'][$productId] ?? 0;
    $_SESSION['cart'][$productId] = $qty + 1;
}

$count = array_sum($_SESSION['cart']);
echo "Cart: " . $count . " item(s)";
cart.php: una página protegida y un carrito almacenado en la sesión.

Las cookies, en cambio, viven en el dispositivo del usuario y sobreviven al cierre del navegador: perfectas para un tema o una preferencia de idioma. Desde PHP 7.3, setcookie() acepta un array de opciones: exige secure (solo HTTPS), httponly (invisible para JavaScript) y samesite (limita el envío desde otros sitios).

PHP
<?php

setcookie('theme', 'dark', [
    'expires' => time() + 60 * 60 * 24 * 30,
    'path' => '/',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Lax',
]);

$theme = $_COOKIE['theme'] ?? 'light';
echo "Active theme: " . $theme;
Una cookie de preferencia válida durante treinta días, con los flags correctos.

Cerrar sesión debe hacerse con tanto cuidado como iniciarla: vacía $_SESSION, destruye la sesión del lado del servidor y caduca la cookie que transportaba el identificador.

PHP
<?php

session_start();

$_SESSION = [];
session_destroy();

setcookie(session_name(), '', time() - 3600, '/');

header('Location: /login.php');
exit;
logout.php: un cierre de sesión completo, sin dejar rastro.

Prueba de conocimientos

Comprueba que has retenido los puntos clave de esta lección.

  1. ¿Dónde se almacenan los datos de una sesión de PHP?
    • En una cookie en el dispositivo del usuario
    • En el servidor; el navegador solo guarda un identificador en una cookie
    • En la URL de cada página
    • En el localStorage del navegador
  2. ¿Por qué llamar a session_regenerate_id(true) justo después de un inicio de sesión exitoso?
    • Para evitar la fijación de sesión: un identificador conocido antes del inicio de sesión queda inutilizable
    • Para prolongar la vida de la cookie de sesión
    • Para borrar los datos antiguos del carrito
  3. ¿Qué hace la opción httponly de una cookie?
    • Cifra el contenido de la cookie
    • Restringe la cookie a conexiones no seguras
    • Hace la cookie inaccesible para el JavaScript de la página, lo que limita el robo mediante XSS