middleware cookie-session

middleware de sesión simple basado en cookies.

Una sesión de usuario puede almacenarse de dos formas principales con cookies: en el servidor o en el cliente. Este módulo almacena los datos de la sesión en el cliente dentro de una cookie, mientras que un módulo como express-session almacena solo un identificador de sesión en el cliente dentro de una cookie y guarda los datos de la sesión en el servidor, típicamente en una base de datos.

Los siguientes puntos pueden ayudarte a elegir cuál usar:

  • cookie-session no requiere ninguna base de datos / recursos en el lado del servidor, aunque los datos totales de la sesión no pueden exceder el tamaño máximo de cookie del navegador.
  • cookie-session puede simplificar ciertos escenarios con balanceo de carga.
  • cookie-session puede usarse para almacenar una sesión “ligera” e incluir un identificador para buscar en un almacén secundario respaldado por base de datos y reducir las consultas a la base de datos.

NOTA Este módulo no cifra el contenido de la sesión en la cookie, solo proporciona firma para evitar manipulaciones. El cliente podrá leer los datos de la sesión examinando el valor de la cookie. No se deben establecer datos secretos en req.session sin cifrarlos, o usar en su lugar una sesión del lado del servidor.

NOTA Este módulo no previene el replay de sesión, ya que la expiración establecida es solo la de la cookie; si esto es una preocupación para tu aplicación, puedes almacenar una fecha de expiración en el objeto req.session y validarla en el servidor, e implementar cualquier otra lógica para extender la sesión según las necesidades de tu aplicación.

Instalar

Este es un módulo de Node.js disponible a través del registro npm. La instalación se hace usando el comando npm install:

Ventana de terminal
npm install cookie-session

API

var cookieSession = require('cookie-session');
var express = require('express');
var app = express();
app.use(
cookieSession({
name: 'session',
keys: [
/* secret keys */
],
// Cookie Options
maxAge: 24 * 60 * 60 * 1000, // 24 hours
})
);

cookieSession(options)

Crea un nuevo middleware de sesión con cookies con las opciones proporcionadas. Este middleware adjuntará la propiedad session a req, que proporciona un objeto que representa la sesión cargada. Esta sesión es una sesión nueva si no se proporcionó una sesión válida en la petición, o una sesión cargada desde la petición.

El middleware añadirá automáticamente un encabezado Set-Cookie a la respuesta si el contenido de req.session fue alterado. Ten en cuenta que no habrá ningún encabezado Set-Cookie en la respuesta (y por lo tanto no se creará ninguna sesión para un usuario específico) a menos que haya contenidos en la sesión, así que asegúrate de añadir algo a req.session tan pronto como tengas información identificativa que almacenar para la sesión.

Opciones

Cookie session acepta estas propiedades en el objeto de opciones.

name

El nombre de la cookie a establecer, por defecto session.

keys

La lista de claves a usar para firmar y verificar los valores de las cookies, o una instancia configurada de Keygrip. Las cookies establecidas siempre se firman con keys[0], mientras que las demás claves son válidas para verificación, permitiendo la rotación de claves. Si se proporciona una instancia de Keygrip, puede usarse para cambiar parámetros de firma como el algoritmo de la firma.

secret

Una cadena que se usará como clave única si no se proporciona keys.

Otras opciones se pasan a cookies.get() y cookies.set() permitiéndote controlar seguridad, dominio, ruta y firma, entre otras configuraciones.

Las opciones también pueden contener cualquiera de las siguientes (para la lista completa, consulta la documentación del módulo cookies:

  • maxAge: un número que representa los milisegundos desde Date.now() para la expiración
  • expires: un objeto Date que indica la fecha de expiración de la cookie (expira al final de la sesión por defecto).
  • path: una cadena que indica la ruta de la cookie (/ por defecto).
  • domain: una cadena que indica el dominio de la cookie (sin valor por defecto).
  • partitioned: un booleano que indica si se debe particionar la cookie en Chrome para la CHIPS Update (false por defecto). Si es true, las cookies de sitios embebidos se particionarán y solo serán legibles desde el mismo sitio de nivel superior desde el que fueron creadas.
  • priority: una cadena que indica la prioridad de la cookie. Puede establecerse como 'low', 'medium', o 'high'.
  • sameSite: un booleano o cadena que indica si la cookie es una cookie “same site” (false por defecto). Puede establecerse como 'strict', 'lax', 'none', o true (que se mapea a 'strict').
  • secure: un booleano que indica si la cookie solo debe enviarse sobre HTTPS (false por defecto para HTTP, true por defecto para HTTPS). Si se establece como true y Node.js no está directamente sobre una conexión TLS, asegúrate de leer cómo configurar Express detrás de proxies o la cookie podría no establecerse correctamente nunca.
  • httpOnly: un booleano que indica si la cookie solo debe enviarse sobre HTTP(S), y no estar disponible para el JavaScript del cliente (true por defecto).
  • signed: un booleano que indica si la cookie debe firmarse (true por defecto).
  • overwrite: un booleano que indica si se deben sobrescribir las cookies previamente establecidas con el mismo nombre (true por defecto).

req.session

Representa la sesión para la petición dada.

.isChanged

Es true si la sesión ha sido modificada durante la petición.

.isNew

Es true si la sesión es nueva.

.isPopulated

Determina si la sesión ha sido poblada con datos o está vacía.

req.sessionOptions

Representa las opciones de sesión para la petición actual. Estas opciones son un clon superficial de lo que se proporcionó en la construcción del middleware y pueden alterarse para cambiar el comportamiento de configuración de cookies por petición.

Destruir una sesión

Para destruir una sesión simplemente establécela como null:

req.session = null;

Guardar una sesión

Dado que todo el contenido de la sesión se mantiene en una cookie del lado del cliente, la sesión se “guarda” escribiendo una cookie en un encabezado de respuesta Set-Cookie. Esto se hace automáticamente si se ha realizado un cambio en la sesión cuando los encabezados de respuesta de Node.js se están escribiendo al cliente y la sesión no fue destruida.

Ejemplos

Ejemplo simple de contador de vistas

var cookieSession = require('cookie-session');
var express = require('express');
var app = express();
app.set('trust proxy', 1); // trust first proxy
app.use(
cookieSession({
name: 'session',
keys: ['key1', 'key2'],
})
);
app.get('/', function (req, res, next) {
// Update views
req.session.views = (req.session.views || 0) + 1;
// Write response
res.end(req.session.views + ' views');
});
app.listen(3000);

Edad máxima persistente por usuario

var cookieSession = require('cookie-session');
var express = require('express');
var app = express();
app.set('trust proxy', 1); // trust first proxy
app.use(
cookieSession({
name: 'session',
keys: ['key1', 'key2'],
})
);
// This allows you to set req.session.maxAge to let certain sessions
// have a different value than the default.
app.use(function (req, res, next) {
req.sessionOptions.maxAge = req.session.maxAge || req.sessionOptions.maxAge;
next();
});
// ... your logic here ...

Extender la expiración de la sesión

Este módulo no envía un encabezado Set-Cookie si el contenido de la sesión no ha cambiado. Esto significa que para extender la expiración de una sesión en el navegador del usuario (en respuesta a la actividad del usuario, por ejemplo) se debe realizar algún tipo de modificación en la sesión.

var cookieSession = require('cookie-session');
var express = require('express');
var app = express();
app.use(
cookieSession({
name: 'session',
keys: ['key1', 'key2'],
})
);
// Update a value in the cookie so that the set-cookie will be sent.
// Only changes every minute so that it's not sent with every request.
app.use(function (req, res, next) {
req.session.nowInMinutes = Math.floor(Date.now() / 60e3);
next();
});
// ... your logic here ...

Usar un algoritmo de firma personalizado

Este ejemplo muestra la creación de una instancia personalizada de Keygrip como opción keys para proporcionar claves y configuración de firma adicional.

var cookieSession = require('cookie-session');
var express = require('express');
var Keygrip = require('keygrip');
var app = express();
app.use(
cookieSession({
name: 'session',
keys: new Keygrip(['key1', 'key2'], 'SHA384', 'base64'),
})
);
// ... your logic here ...

Limitaciones de uso

Dado que todo el objeto de sesión se codifica y almacena en una cookie, es posible exceder los límites máximos de tamaño de cookie en diferentes navegadores. La especificación RFC6265 recomienda que un navegador DEBERÍA permitir

Al menos 4096 bytes por cookie (medido por la suma de la longitud del nombre, valor y atributos de la cookie)

En la práctica, este límite varía ligeramente entre navegadores. Consulta una lista de límites de navegadores aquí. Como regla general no excedas los 4093 bytes por dominio.

Si tu objeto de sesión es lo suficientemente grande para exceder un límite del navegador al codificarse, en la mayoría de los casos el navegador se negará a almacenar la cookie. Esto causará que las siguientes peticiones del navegador a) no tengan ninguna información de sesión o b) usen información de sesión antigua que era lo suficientemente pequeña como para no exceder el límite de la cookie.

Si encuentras que tu objeto de sesión está alcanzando estos límites, es mejor considerar si los datos de tu sesión deberían cargarse desde una base de datos en el servidor en lugar de transmitirse hacia/desde el navegador con cada petición. O moverse a una estrategia de sesión alternativa

Licencia

MIT