Saltar a contenido

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