¿Cuáles son los caracteres permitidos en las cookies?

Publicado 27 de agosto de 2024

Problema: Restricciones en los caracteres de las cookies

Al crear cookies para aplicaciones web, es necesario conocer los límites de caracteres. No todos los caracteres se pueden usar en los nombres y valores de las cookies. Esto puede causar problemas si se usan incorrectamente. Conocer estos límites es clave para que las cookies funcionen bien y para evitar riesgos de seguridad.

Implementación de restricciones de caracteres en cookies por los navegadores

Prácticas comunes de los navegadores

Los navegadores web manejan las restricciones de caracteres en cookies de manera similar para seguir los estándares web. Aquí algunas prácticas comunes:

Codificación URL de caracteres especiales

Los navegadores aplican codificación URL a los caracteres especiales en los valores de las cookies. Esto convierte los caracteres no permitidos en URLs a un formato seguro.

Carácter Codificado URL
Espacio %20
= %3D
& %26
+ %2B
/ %2F

Ejemplo: Configurando una cookie con caracteres especiales

document.cookie = "user_info=John Doe & Co.; path=/";
// El navegador lo almacena como: user_info=John%20Doe%20%26%20Co.

Manejo de caracteres no ASCII

La mayoría de los navegadores admiten codificación UTF-8 para caracteres no ASCII en valores de cookies. Es mejor codificar estos caracteres manualmente:

Ejemplo: Codificando caracteres no ASCII

const userName = "José";
document.cookie = `user=${encodeURIComponent(userName)}; path=/`;
// El navegador lo almacena como: user=Jos%C3%A9

Limitaciones específicas de los navegadores

Los navegadores generalmente siguen prácticas similares, pero puede haber diferencias en cómo manejan las cookies.

Consejo: Limitaciones de cookies en navegadores

  • Chrome: Hasta 180 cookies por dominio, 4096 bytes por cookie
  • Firefox: Hasta 150 cookies por dominio, 4097 bytes por cookie
  • Safari: Hasta 600 cookies en total, 4093 bytes por cookie
  • Internet Explorer: Hasta 50 cookies por dominio, 4096 bytes por cookie

Estrategias para trabajar con las limitaciones de los navegadores

  1. Dividir datos grandes en múltiples cookies

Ejemplo: Dividiendo datos grandes en múltiples cookies

function setLargeCookie(name, value) {
    const maxLength = 4000;
    const parts = Math.ceil(value.length / maxLength);

    for (let i = 0; i < parts; i++) {
        const part = value.substr(i * maxLength, maxLength);
        document.cookie = `${name}_${i}=${part}; path=/`;
    }
}

// Uso
setLargeCookie("user_data", "cadena_muy_larga_de_datos_de_usuario");
  1. Usar almacenamiento local para datos del lado del cliente que no necesitan ser enviados con cada solicitud

Ejemplo: Usando almacenamiento local para datos grandes

// Almacenando datos grandes en almacenamiento local
localStorage.setItem('user_preferences', JSON.stringify(objetoGrandeDePreferenciasDeUsuario));

// Recuperando datos del almacenamiento local
const userPreferences = JSON.parse(localStorage.getItem('user_preferences'));
  1. Implementar un mecanismo de respaldo para navegadores con límites más estrictos

Ejemplo: Mecanismo de respaldo para almacenamiento de cookies

function setCookie(name, value, days) {
    try {
        document.cookie = `${name}=${value}; max-age=${days * 24 * 60 * 60}; path=/`;
    } catch (error) {
        console.warn(`Error al establecer cookie: ${error.message}`);
        localStorage.setItem(name, value);
    }
}

function getCookie(name) {
    const value = document.cookie.match('(^|;)\\s*' + name + '\\s*=\\s*([^;]+)');
    return value ? value.pop() : localStorage.getItem(name);
}

Manejo de caracteres internacionales

Al tratar con caracteres internacionales en cookies, considera estos enfoques:

  1. Usar encodeURIComponent() para codificar y decodeURIComponent() para decodificar
  2. Para escenarios más complejos, usar btoa() y atob() para codificación Base64

Ejemplo: Manejo de caracteres internacionales en cookies

// Codificando caracteres internacionales
const internationalName = "안녕하세요";
document.cookie = `greeting=${encodeURIComponent(internationalName)}; path=/`;

// Decodificando
const storedGreeting = decodeURIComponent(getCookie('greeting'));

// Codificación Base64 para datos complejos
const complexData = { name: "José", age: 30, city: "São Paulo" };
document.cookie = `userData=${btoa(JSON.stringify(complexData))}; path=/`;

// Decodificando Base64
const decodedData = JSON.parse(atob(getCookie('userData')));

Consideraciones sobre atributos de cookies

Atributo de dominio y limitaciones de caracteres

El atributo de dominio en las cookies define qué hosts pueden recibir la cookie. Aquí hay puntos clave sobre el atributo de dominio y sus limitaciones de caracteres:

Caracteres permitidos

  • Caracteres alfanuméricos (a-z, A-Z, 0-9)
  • Guiones (-)
  • Puntos (.)

Reglas para nombres de dominio

  • Deben comenzar y terminar con caracteres alfanuméricos
  • No pueden contener puntos consecutivos
  • Longitud máxima de 253 caracteres

Consideraciones de subdominio

  • Establecer el dominio a un subdominio específico limita la cookie a ese subdominio
  • Usar un punto inicial (.) permite que la cookie se comparta con subdominios

Ejemplo: Configuraciones de dominio válidas e inválidas

Configuraciones de dominio válidas Configuraciones de dominio inválidas
example.com .example.com (punto inicial)
sub.example.com example..com (puntos consecutivos)
mi-sitio.com -example.com (empieza con guion)
123.example.com example.com- (termina con guion)

Ejemplo: Configurando el atributo de dominio

// Cookie para un subdominio específico
document.cookie = "name=value; domain=subdominio.ejemplo.com";

// Cookie compartida con todos los subdominios
document.cookie = "name=value; domain=ejemplo.com";

Atributos Expires y Max-Age

Los atributos Expires y Max-Age controlan cuándo debe eliminarse una cookie.

Atributo Expires

  • Usa la zona horaria GMT/UTC
  • Formato: "Wdy, DD-Mon-YYYY HH:MM:SS GMT"
  • Ejemplo: "Wed, 21 Oct 2023 07:28:00 GMT"

Atributo Max-Age

  • Entero positivo que representa segundos
  • El valor máximo depende de la implementación del navegador (típicamente alrededor de 2^31 - 1)

Ejemplo: Expires vs Max-Age

Característica Expires Max-Age
Referencia de tiempo Fecha absoluta Relativo al tiempo actual
Formato Cadena de fecha Número de segundos
Soporte del navegador Todos los navegadores La mayoría de navegadores modernos
Precedencia Menor Mayor (si ambos están configurados)

Ejemplo: Configurando la expiración

// Usando el atributo Expires
const expirationDate = new Date();
expirationDate.setDate(expirationDate.getDate() + 7);
document.cookie = `name=value; expires=${expirationDate.toUTCString()}`;

// Usando el atributo Max-Age (7 días en segundos)
document.cookie = "name=value; max-age=604800";

Atributos adicionales de cookies

Atributo Secure

  • Asegura que la cookie solo se envíe a través de HTTPS
  • Uso: document.cookie = "name=value; secure";

Atributo HttpOnly

  • Impide el acceso a la cookie a través de scripts del lado del cliente
  • Ayuda a reducir ataques de cross-site scripting (XSS)
  • Uso: document.cookie = "name=value; HttpOnly";

Atributo SameSite

Controla cuándo se envían las cookies con solicitudes de sitios cruzados:

  • Strict: Solo se envía para solicitudes del mismo sitio
  • Lax: Se envía para el mismo sitio y navegación de nivel superior desde sitios externos
  • None: Permite el envío entre sitios (requiere el atributo Secure)

Ejemplo: Configurando el atributo SameSite

document.cookie = "name=value; SameSite=Strict";