session: Biblioteca de sesiones para nginx-module-lua – flexible y segura
Instalación
Si no ha configurado la suscripción al repositorio RPM, regístrese. Luego puede continuar con los siguientes pasos.
CentOS/RHEL 7 o Amazon Linux 2
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install lua-resty-session
CentOS/RHEL 8+, Fedora Linux, Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-session
Para usar esta biblioteca Lua con NGINX, asegúrese de que nginx-module-lua esté instalado.
Este documento describe lua-resty-session v4.2.0 publicada el 24 de agosto de 2026.
lua-resty-session es una biblioteca de sesiones segura y flexible para OpenResty.
TL;DR;
- Las sesiones son inmutables (cada guardado genera una nueva sesión) y sin bloqueos.
- Los datos de la sesión están cifrados con AES-256-GCM utilizando una clave derivada con HKDF-SHA256 (en modo FIPS se utiliza PBKDF2 con SHA-256 en su lugar).
- La sesión tiene un encabezado de tamaño fijo que está protegido con HMAC-SHA256 MAC con una clave derivada utilizando HKDF-SHA256 (en modo FIPS se utiliza PBKDF2 con SHA-256 en su lugar).
- Los datos de la sesión se pueden almacenar en una cookie sin estado o en varios almacenamientos backend.
- Una sola cookie de sesión puede mantener múltiples sesiones en diferentes audiencias.
Nota: La versión 4.0.0 fue una reescritura de esta biblioteca con muchas lecciones aprendidas durante los años. Si aún utiliza una versión anterior, consulte la documentación antigua.
Sinopsis
worker_processes 1;
events {
worker_connections 1024;
}
http {
init_by_lua_block {
require "resty.session".init({
remember = true,
audience = "demo",
secret = "RaJKp8UQW1",
storage = "cookie",
})
}
server {
listen 8080;
server_name localhost;
default_type text/html;
location / {
content_by_lua_block {
ngx.say([[
<html>
<body>
<a href=/start>Start the test</a>
</body>
</html>
]])
}
}
location /start {
content_by_lua_block {
local session = require "resty.session".new()
session:set_subject("OpenResty Fan")
session:set("quote", "The quick brown fox jumps over the lazy dog")
local ok, err = session:save()
ngx.say(string.format([[
<html>
<body>
<p>Session started (%s)</p>
<p><a href=/started>Check if it really was</a></p>
</body>
</html>
]], err or "no error"))
}
}
location /started {
content_by_lua_block {
local session, err = require "resty.session".start()
ngx.say(string.format([[
<html>
<body>
<p>Session was started by %s (%s)</p>
<p><blockquote>%s</blockquote></p>
<p><a href=/modify>Modify the session</a></p>
</body>
</html>
]],
session:get_subject() or "Anonymous",
err or "no error",
session:get("quote") or "no quote"
))
}
}
location /modify {
content_by_lua_block {
local session, err = require "resty.session".start()
session:set_subject("Lua Fan")
session:set("quote", "Lorem ipsum dolor sit amet")
local _, err_save = session:save()
ngx.say(string.format([[
<html>
<body>
<p>Session was modified (%s)</p>
<p><a href=/modified>Check if it is modified</a></p>
</body>
</html>
]], err or err_save or "no error"))
}
}
location /modified {
content_by_lua_block {
local session, err = require "resty.session".start()
ngx.say(string.format([[
<html>
<body>
<p>Session was started by %s (%s)</p>
<p><blockquote>%s</blockquote></p>
<p><a href=/destroy>Destroy the session</a></p>
</body>
</html>
]],
session:get_subject() or "Anonymous",
err or "no error",
session:get("quote") or "no quote"
))
}
}
location /destroy {
content_by_lua_block {
local ok, err = require "resty.session".destroy()
ngx.say(string.format([[
<html>
<body>
<p>Session was destroyed (%s)</p>
<p><a href=/destroyed>Check that it really was?</a></p>
</body>
</html>
]], err or "no error"))
}
}
location /destroyed {
content_by_lua_block {
local session, err = require "resty.session".open()
ngx.say(string.format([[
<html>
<body>
<p>Session was really destroyed, you are known as %s (%s)</p>
<p><a href=/>Start again</a></p>
</body>
</html>
]],
session:get_subject() or "Anonymous",
err or "no error"
))
}
}
}
}
Configuración
La configuración se puede dividir en configuración genérica de sesión y configuración de almacenamiento del lado del servidor.
Aquí hay un ejemplo:
init_by_lua_block {
require "resty.session".init({
remember = true,
store_metadata = true,
secret = "RaJKp8UQW1",
secret_fallbacks = {
"X88FuG1AkY",
"fxWNymIpbb",
},
storage = "postgres",
postgres = {
username = "my-service",
password = "kVgIXCE5Hg",
database = "sessions",
},
})
}
Configuración de sesión
La configuración de sesión se puede pasar a las funciones de inicialización, constructores, y helpers.
Aquí están las opciones de configuración de sesión posibles:
| Opción | Default | Descripción |
|---|---|---|
secret |
nil |
Secreto utilizado para la derivación de claves. El secreto se procesa con SHA-256 antes de usarlo. Ej. "RaJKp8UQW1". |
secret_fallbacks |
nil |
Matriz de secretos que se pueden usar como secretos alternativos (al hacer rotación de claves), Ej. { "6RfrAYYzYq", "MkbTkkyF9C" }. |
ikm |
(aleatorio) | El material de clave inicial (o ikm) se puede especificar directamente (sin usar un secreto) con exactamente 32 bytes de datos. Ej. "5ixIW4QVMk0dPtoIhn41Eh1I9enP2060" |
ikm_fallbacks |
nil |
Matriz de materiales de clave iniciales que se pueden usar como claves alternativas (al hacer rotación de claves), Ej. { "QvPtlPKxOKdP5MCu1oI3lOEXIVuDckp7" }. |
cookie_prefix |
nil |
Prefijo de cookie, use nil, "__Host-" o "__Secure-". |
cookie_name |
"session" |
Nombre de la cookie de sesión, ej. "session". |
cookie_path |
"/" |
Ruta de la cookie, ej. "/". |
cookie_domain |
nil |
Dominio de la cookie, ej. "example.com" |
cookie_http_only |
true |
Marcar la cookie como solo HTTP, use true o false. |
cookie_secure |
nil |
Marcar la cookie como segura, use nil, true o false. |
cookie_priority |
nil |
Prioridad de la cookie, use nil, "Low", "Medium" o "High". |
cookie_same_site |
"Lax" |
Política same-site de la cookie, use nil, "Lax", "Strict", "None" o "Default" |
cookie_same_party |
nil |
Marcar la cookie con el indicador same party, use nil, true o false. |
cookie_partitioned |
nil |
Marcar la cookie con el indicador partitioned, use nil, true o false. |
remember |
false |
Habilitar o deshabilitar sesiones persistentes, use nil, true o false. |
remember_safety |
"Medium" |
Complejidad de derivación de clave de la cookie remember, use nil, "None" (rápido), "Low", "Medium", "High" o "Very High" (lento). |
remember_cookie_name |
"remember" |
Nombre de la cookie de sesión persistente, ej. "remember". |
audience |
"default" |
Audiencia de la sesión, ej. "my-application". |
subject |
nil |
Sujeto de la sesión, ej. "[email protected]". |
enforce_same_subject |
false |
Cuando se establece en true, las audiencias deben compartir el mismo sujeto. La biblioteca elimina los datos de audiencia que no coinciden con el sujeto al guardar. |
stale_ttl |
10 |
Cuando se guarda una sesión, se crea una nueva sesión; stale ttl especifica cuánto tiempo se puede seguir usando la anterior, ej. 10 (en segundos). |
idling_timeout |
900 |
El tiempo de inactividad especifica cuánto tiempo puede estar inactiva la sesión hasta que se considere inválida, ej. 900 (15 minutos) (en segundos), 0 deshabilita las comprobaciones y el toque. |
rolling_timeout |
3600 |
El tiempo de renovación especifica cuánto tiempo se puede usar la sesión hasta que necesite renovarse, ej. 3600 (una hora) (en segundos), 0 deshabilita las comprobaciones y la renovación. |
absolute_timeout |
86400 |
El tiempo absoluto limita cuánto tiempo se puede renovar la sesión, hasta que se requiera re-autenticación, ej. 86400 (un día) (en segundos), 0 deshabilita las comprobaciones. |
remember_rolling_timeout |
604800 |
El tiempo de remember especifica cuánto tiempo se considera válida la sesión persistente, ej. 604800 (una semana) (en segundos), 0 deshabilita las comprobaciones y la renovación. |
remember_absolute_timeout |
2592000 |
El tiempo absoluto de remember limita cuánto tiempo se puede renovar la sesión persistente, hasta que se requiera re-autenticación, ej. 2592000 (30 días) (en segundos), 0 deshabilita las comprobaciones. |
hash_storage_key |
false |
Si se debe procesar o no la clave de almacenamiento. Con la clave de almacenamiento procesada es imposible descifrar datos en el lado del servidor sin tener también una cookie, use nil, true o false. |
hash_subject |
false |
Si se debe procesar o no el sujeto cuando store_metadata está habilitado, ej. por razones de PII. |
store_metadata |
false |
Si también se deben almacenar metadatos de sesiones, como recopilar datos de sesiones para una audiencia específica que pertenece a un sujeto específico. |
touch_threshold |
60 |
El umbral de toque controla con qué frecuencia o infrecuencia session:refresh toca la cookie, ej. 60 (un minuto) (en segundos) |
compression_threshold |
1024 |
El umbral de compresión controla cuándo se comprimen los datos, ej. 1024 (un kilobyte) (en bytes), 0 deshabilita la compresión. |
bind |
nil |
Vincular la sesión a datos adquiridos de la solicitud HTTP o conexión, use ip, scheme, user-agent. Ej. { "scheme", "user-agent" } calculará MAC utilizando también el Scheme de la solicitud HTTP y el encabezado User-Agent. |
request_headers |
nil |
Conjunto de encabezados para enviar al upstream, use id, audience, subject, timeout, idling-timeout, rolling-timeout, absolute-timeout. Ej. { "id", "timeout" } establecerá los encabezados de solicitud Session-Id y Session-Timeout cuando se llame a set_headers. |
response_headers |
nil |
Conjunto de encabezados para enviar al downstream, use id, audience, subject, timeout, idling-timeout, rolling-timeout, absolute-timeout. Ej. { "id", "timeout" } establecerá los encabezados de respuesta Session-Id y Session-Timeout cuando se llame a set_headers. |
storage |
nil |
El almacenamiento es responsable de almacenar los datos de la sesión, use nil o "cookie" (los datos se almacenan en la cookie), "dshm", "file", "memcached", "mysql", "postgres", "redis" o "shm", o dé un nombre de módulo personalizado ("custom-storage"), o una tabla que implemente la interfaz de almacenamiento de sesiones. |
revocation |
nil |
Almacenamiento utilizado para registros de revocación de sesiones de cookie. Use nil o false para deshabilitar, un nombre de almacenamiento como "shm", "redis", "mysql" o "postgres", un nombre de módulo de almacenamiento personalizado, o una tabla de almacenamiento con métodos set/get. |
revocation_fail_mode |
"open" |
Comportamiento cuando el almacén de revocación no está disponible, use "open" (tratar como no revocado) o "closed" (rechazar la sesión). |
dshm |
nil |
Configuración para almacenamiento dshm, ej. { prefix = "sessions" } (ver abajo) |
file |
nil |
Configuración para almacenamiento de archivos, ej. { path = "/tmp", suffix = "session" } (ver abajo) |
memcached |
nil |
Configuración para almacenamiento memcached, ej. { prefix = "sessions" } (ver abajo) |
mysql |
nil |
Configuración para almacenamiento MySQL / MariaDB, ej. { database = "sessions" } (ver abajo) |
postgres |
nil |
Configuración para almacenamiento Postgres, ej. { database = "sessions" } (ver abajo) |
redis |
nil |
Configuración para almacenamientos Redis / Redis Sentinel / Redis Cluster, ej. { prefix = "sessions" } (ver abajo) |
shm |
nil |
Configuración para almacenamiento de memoria compartida, ej. { zone = "sessions" } |
["custom-storage"] |
nil |
Configuración de almacenamiento personalizado (cargado con require "custom-storage"). |
Configuración de almacenamiento de cookies
Al almacenar datos en una cookie, no se requiere configuración adicional,
solo establezca storage en nil o "cookie".
Configuración de revocación de sesiones
Las sesiones de cookie (sin estado) son autocontenidas: una vez emitidas, una cookie permanece válida hasta que expire según los tiempos de espera configurados. La revocación agrega una lista de denegación opcional respaldada por almacenamiento para que las sesiones destruidas se rechacen inmediatamente, sin esperar a que la cookie expire.
La revocación solo está disponible cuando los datos de la sesión se almacenan en la cookie
(storage es nil o "cookie"). Seleccione el backend explícitamente con
revocation = "dshm", "file", "memcached", "mysql", "postgres",
"redis" o "shm". El backend utiliza su sección de configuración normal y
el mismo contrato de almacenamiento set/get utilizado para los datos de sesión. Los nombres
de módulos de almacenamiento personalizados y las tablas de almacenamiento preconstruidas también son compatibles. Establecer
revocation = false o dejarlo sin configurar deshabilita la revocación.
En cada session:open, la biblioteca verifica si el identificador de sesión está
revocado. En session:destroy, el identificador se escribe en el almacenamiento
seleccionado con un TTL igual a la vida útil restante de la sesión (tiempos de espera
de renovación y absolutos). La marca de revocación es un centinela ligero; no se almacena
ningún payload de sesión.
Use revocation_fail_mode para controlar el comportamiento cuando el almacenamiento no está disponible:
"open"(predeterminado): registra una advertencia y trata la sesión como no revocada. Destroy aún limpia la cookie incluso si la escritura de revocación falla."closed": rechaza la operación de apertura o destrucción de la sesión.
La revocación se aplica a session:destroy (y session:logout cuando destruye
la última audiencia). No revoca el identificador de sesión anterior en
session:save (rotación de sesión) o session:logout parcial (múltiples
audiencias). Después de la rotación o el cierre de sesión parcial, la cookie anterior permanece
utilizable hasta que su stale_ttl o tiempo de espera expire.
Ejemplos:
-- Lista de denegación Redis
require("resty.session").init({
storage = "cookie",
revocation = "redis",
redis = {
host = "127.0.0.1",
password = "secret",
prefix = "sessions",
},
})
-- Lista de denegación de memoria compartida
require("resty.session").init({
storage = "cookie",
revocation = "shm",
shm = {
zone = "sessions",
prefix = "revocations",
},
})
-- Lista de denegación MySQL
require("resty.session").init({
storage = "cookie",
revocation = "mysql",
mysql = {
host = "127.0.0.1",
database = "sessions",
username = "session",
password = "secret",
},
})
El mismo patrón funciona para "dshm", "file", "memcached" y "postgres".
Configuración de almacenamiento DSHM
Con almacenamiento DHSM puede usar las siguientes configuraciones (establezca storage en "dshm"):
| Opción | Default | Descripción |
|---|---|---|
prefix |
nil |
El prefijo para las claves almacenadas en DSHM. |
suffix |
nil |
El sufijo para las claves almacenadas en DSHM. |
host |
"127.0.0.1" |
El host al que conectarse. |
port |
4321 |
El puerto al que conectarse. |
connect_timeout |
nil |
Controla el valor de tiempo de espera predeterminado utilizado en el método connect del objeto de socket TCP/socket de dominio Unix. |
send_timeout |
nil |
Controla el valor de tiempo de espera predeterminado utilizado en el método send del objeto de socket TCP/socket de dominio Unix. |
read_timeout |
nil |
Controla el valor de tiempo de espera predeterminado utilizado en el método receive del objeto de socket TCP/socket de dominio Unix. |
keepalive_timeout |
nil |
Controla el tiempo máximo de inactividad predeterminado de las conexiones en el pool de conexiones. |
pool |
nil |
Un nombre personalizado para el pool de conexiones que se está utilizando. |
pool_size |
nil |
El tamaño del pool de conexiones. |
backlog |
nil |
Un tamaño de cola para usar cuando el pool de conexiones está lleno (configurado con pool_size). |
ssl |
nil |
Habilitar SSL. |
ssl_verify |
nil |
Verificar el certificado del servidor. |
server_name |
nil |
El nombre del servidor para la nueva extensión TLS Server Name Indication (SNI). |
Consulte ngx-distributed-shm para obtener las dependencias necesarias instaladas.
Configuración de almacenamiento de archivos
Con almacenamiento de archivos puede usar las siguientes configuraciones (establezca storage en "file"):
| Opción | Default | Descripción |
|---|---|---|
prefix |
nil |
Prefijo de archivo para el archivo de sesión. |
suffix |
nil |
Sufijo de archivo (o extensión sin .) para el archivo de sesión. |
pool |
nil |
Nombre del pool de hilos bajo el cual ocurre la escritura de archivos (disponible solo en Linux). |
path |
(directorio tmp) | Ruta (o directorio) bajo la cual se crean los archivos de sesión. |
La implementación requiere LuaFileSystem que puede instalar con LuaRocks:
❯ luarocks install LuaFileSystem
Configuración de almacenamiento Memcached
Con Memcached puede usar las siguientes configuraciones (establezca storage en "memcached"):
| Opción | Default | Descripción |
|---|---|---|
prefix |
nil |
Prefijo para las claves almacenadas en memcached. |
suffix |
nil |
Sufijo para las claves almacenadas en memcached. |
host |
127.0.0.1 |
El host al que conectarse. |
port |
11211 |
El puerto al que conectarse. |
socket |
nil |
El archivo de socket al que conectarse. |
connect_timeout |
nil |
Controla el valor de tiempo de espera predeterminado utilizado en el método connect del objeto de socket TCP/socket de dominio Unix. |
send_timeout |
nil |
Controla el valor de tiempo de espera predeterminado utilizado en el método send del objeto de socket TCP/socket de dominio Unix. |
read_timeout |
nil |
Controla el valor de tiempo de espera predeterminado utilizado en el método receive del objeto de socket TCP/socket de dominio Unix. |
keepalive_timeout |
nil |
Controla el tiempo máximo de inactividad predeterminado de las conexiones en el pool de conexiones. |
pool |
nil |
Un nombre personalizado para el pool de conexiones que se está utilizando. |
pool_size |
nil |
El tamaño del pool de conexiones. |
backlog |
nil |
Un tamaño de cola para usar cuando el pool de conexiones está lleno (configurado con pool_size). |
ssl |
false |
Habilitar SSL |
ssl_verify |
nil |
Verificar el certificado del servidor |
server_name |
nil |
El nombre del servidor para la nueva extensión TLS Server Name Indication (SNI). |
Configuración de almacenamiento MySQL / MariaDB
Con MySQL / MariaDB puede usar las siguientes configuraciones (establezca storage en "mysql"):
| Opción | Default | Descripción |
|---|---|---|
host |
"127.0.0.1" |
El host al que conectarse. |
port |
3306 |
El puerto al que conectarse. |
socket |
nil |
El archivo de socket al que conectarse. |
username |
nil |
El nombre de usuario de la base de datos para autenticarse. |
password |
nil |
Contraseña para autenticación, puede ser requerida dependiendo de la configuración del servidor. |
charset |
"ascii" |
El conjunto de caracteres utilizado en la conexión MySQL. |
database |
nil |
El nombre de la base de datos a la que conectarse. |
table_name |
"sessions" |
Nombre de la tabla de la base de datos en la que almacenar los datos de sesión. |
table_name_meta |
"sessions_meta" |
Nombre de la tabla de metadatos de la base de datos en la que almacenar los metadatos de sesión. |
max_packet_size |
1048576 |
El límite superior para los paquetes de respuesta enviados desde el servidor MySQL (en bytes). |
connect_timeout |
nil |
Controla el valor de tiempo de espera predeterminado utilizado en el método connect del objeto de socket TCP/socket de dominio Unix. |
send_timeout |
nil |
Controla el valor de tiempo de espera predeterminado utilizado en el método send del objeto de socket TCP/socket de dominio Unix. |
read_timeout |
nil |
Controla el valor de tiempo de espera predeterminado utilizado en el método receive del objeto de socket TCP/socket de dominio Unix. |
keepalive_timeout |
nil |
Controla el tiempo máximo de inactividad predeterminado de las conexiones en el pool de conexiones. |
pool |
nil |
Un nombre personalizado para el pool de conexiones que se está utilizando. |
pool_size |
nil |
El tamaño del pool de conexiones. |
backlog |
nil |
Un tamaño de cola para usar cuando el pool de conexiones está lleno (configurado con pool_size). |
ssl |
false |
Habilitar SSL. |
ssl_verify |
nil |
Verificar el certificado del servidor. |
También necesita crear las siguientes tablas en su base de datos:
--
-- Tabla de base de datos que almacena datos de sesión.
--
CREATE TABLE IF NOT EXISTS sessions (
sid CHAR(43) PRIMARY KEY,
name VARCHAR(255),
data MEDIUMTEXT,
exp DATETIME,
INDEX (exp)
) CHARACTER SET ascii;
--
-- Tabla de metadatos de sesiones.
--
-- Esto solo es necesario si desea almacenar metadatos de sesión.
--
CREATE TABLE IF NOT EXISTS sessions_meta (
aud VARCHAR(255),
sub VARCHAR(255),
sid CHAR(43),
PRIMARY KEY (aud, sub, sid),
CONSTRAINT FOREIGN KEY (sid) REFERENCES sessions(sid) ON DELETE CASCADE ON UPDATE CASCADE
) CHARACTER SET ascii;
Configuración de Postgres
Con Postgres puede usar las siguientes configuraciones (establezca storage en "postgres"):
| Opción | Default | Descripción |
|---|---|---|
host |
"127.0.0.1" |
El host al que conectarse. |
port |
5432 |
El puerto al que conectarse. |
application |
5432 |
Establezca el nombre de la conexión como se muestra en pg_stat_activity (predeterminado a "pgmoon"). |
username |
"postgres" |
El nombre de usuario de la base de datos para autenticarse. |
password |
nil |
Contraseña para autenticación, puede ser requerida dependiendo de la configuración del servidor. |
database |
nil |
El nombre de la base de datos a la que conectarse. |
table_name |
"sessions" |
Nombre de la tabla de la base de datos en la que almacenar los datos de sesión (puede tener prefijo de esquema de base de datos). |
table_name_meta |
"sessions_meta" |
Nombre de la tabla de metadatos de la base de datos en la que almacenar los metadatos de sesión (puede tener prefijo de esquema de base de datos). |
connect_timeout |
nil |
Controla el valor de tiempo de espera predeterminado utilizado en el método connect del objeto de socket TCP/socket de dominio Unix. |
send_timeout |
nil |
Controla el valor de tiempo de espera predeterminado utilizado en el método send del objeto de socket TCP/socket de dominio Unix. |
read_timeout |
nil |
Controla el valor de tiempo de espera predeterminado utilizado en el método receive del objeto de socket TCP/socket de dominio Unix. |
keepalive_timeout |
nil |
Controla el tiempo máximo de inactividad predeterminado de las conexiones en el pool de conexiones. |
pool |
nil |
Un nombre personalizado para el pool de conexiones que se está utilizando. |
pool_size |
nil |
El tamaño del pool de conexiones. |
backlog |
nil |
Un tamaño de cola para usar cuando el pool de conexiones está lleno (configurado con pool_size). |
ssl |
false |
Habilitar SSL. |
ssl_verify |
nil |
Verificar el certificado del servidor. |
ssl_required |
nil |