libro / blog / sesiones-cookies-php

// sesiones y cookies

Sesiones y cookies en PHP: cómo funcionan y cómo usarlas con seguridad

Gustavo Arias8 min de lectura

TL;DR Una cookie se guarda en el navegador y el usuario puede verla y modificarla; una sesión se guarda en el servidor y el navegador solo conserva su identificador. Usa cookies para preferencias sin importancia y sesiones para todo lo que deba ser confiable, siempre con HttpOnly, Secure y SameSite.

HTTP no tiene memoria: cada petición llega al servidor como si fuera la primera. Sesiones y cookies son las dos herramientas que usa PHP para “recordar” a un usuario entre una página y otra: su login, su carrito, su idioma preferido. En el libro PHP desde cero hasta experto aprendes a manejar sesiones, cookies y superglobales junto con los formularios; este artículo explica cómo funcionan y cómo usarlas sin abrir agujeros de seguridad.

Cookies vs sesiones

CookieSesión
Dónde se guardaEn el navegadorEn el servidor
El usuario puede verla y cambiarlaSíNo (solo tiene el identificador)
TamañoPequeño (unos 4 KB por cookie)Lo que necesites, con sensatez
DuraciónLa que fijes, incluso mesesHasta cerrar el navegador o caducar
Úsala paraPreferencias: idioma, tema, aviso de cookies aceptadoLogin, carrito, datos temporales confiables

De hecho, una sesión usa una cookie: PHP envía al navegador una cookie llamada PHPSESSID con un identificador aleatorio, y guarda los datos en el servidor asociados a ese identificador.

Cookies: crear, leer y borrar

<?php
// Crear: siempre ANTES de imprimir cualquier HTML
setcookie('idioma', 'es', [
    'expires'  => time() + 60 * 60 * 24 * 365, // un año
    'path'     => '/',
    'secure'   => true,     // solo por HTTPS
    'httponly' => true,     // JavaScript no puede leerla
    'samesite' => 'Lax',
]);

// Leer: disponible a partir de la SIGUIENTE petición
$idioma = $_COOKIE['idioma'] ?? 'es';

// Validar: el usuario puede poner cualquier valor
if (!in_array($idioma, ['es', 'en', 'pt'], true)) {
    $idioma = 'es';
}

// Borrar: misma cookie con fecha en el pasado
setcookie('idioma', '', ['expires' => time() - 3600, 'path' => '/']);
Nunca guardes en una cookie datos que decidan permisos, como es_admin=1 o el id del usuario sin firmar. El usuario puede editarla desde las herramientas del navegador en segundos.

Sesiones: el estado en el servidor

<?php
session_start();                 // al principio de cada página que use la sesión

$_SESSION['usuario_id'] = 42;    // guardar
$id = $_SESSION['usuario_id'] ?? null;  // leer
unset($_SESSION['mensaje']);     // borrar un dato

// Mensaje "flash": se muestra una sola vez (p. ej., tras guardar un formulario)
if (isset($_SESSION['flash'])) {
    echo htmlspecialchars($_SESSION['flash']);
    unset($_SESSION['flash']);
}

Ejemplo: un carrito de compras con $_SESSION

El carrito es el ejemplo clásico: el usuario añade productos en distintas páginas y el servidor los recuerda hasta que compra.

<?php
declare(strict_types=1);
session_start();

$_SESSION['carrito'] ??= [];   // [id_producto => cantidad]

function agregarAlCarrito(int $id, int $cantidad = 1): void
{
    $_SESSION['carrito'][$id] = ($_SESSION['carrito'][$id] ?? 0) + $cantidad;
}

function quitarDelCarrito(int $id): void
{
    unset($_SESSION['carrito'][$id]);
}

function totalCarrito(array $precios): float
{
    $total = 0;
    foreach ($_SESSION['carrito'] as $id => $cantidad) {
        $total += ($precios[$id] ?? 0) * $cantidad;
    }
    return $total;
}

// Las acciones que modifican el carrito llegan por POST
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $id = filter_input(INPUT_POST, 'id', FILTER_VALIDATE_INT);
    if ($id) {
        match ($_POST['accion'] ?? '') {
            'agregar' => agregarAlCarrito($id),
            'quitar'  => quitarDelCarrito($id),
            default   => null,
        };
    }
    header('Location: carrito.php');
    exit;
}

Fíjate en que el carrito guarda solo ids y cantidades. Los precios se consultan en la base de datos al mostrar el total, nunca se toman de la sesión ni del formulario: así nadie puede comprar un monitor a un peso.

Seguridad de sesiones y cookies

<?php
session_set_cookie_params([
    'lifetime' => 0,
    'path'     => '/',
    'secure'   => !empty($_SERVER['HTTPS']),
    'httponly' => true,
    'samesite' => 'Lax',
]);
ini_set('session.use_strict_mode', '1'); // rechaza ids de sesión inventados
session_start();

Con estas bases puedes construir un login completo y su flujo de recuperación de contraseña.

Formularios, sesiones y cookies a fondo

El libro PHP desde cero hasta experto enseña a procesar formularios y manejar sesiones, cookies y superglobales como $_GET, $_POST y $_SESSION.

Comprar en Amazon