session: Biblioteca de sessão para nginx-module-lua – flexível e segura
Instalação
Se você ainda não configurou a assinatura do repositório RPM, cadastre-se. Em seguida, você pode prosseguir com os seguintes passos.
CentOS/RHEL 7 ou 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 com NGINX, certifique-se de que o nginx-module-lua esteja instalado.
Este documento descreve o lua-resty-session v4.2.0 lançado em 24 de agosto de 2026.
lua-resty-session é uma biblioteca de sessão segura e flexível para OpenResty.
Resumo;
- As sessões são imutáveis (cada salvamento gera uma nova sessão) e sem bloqueio.
- Os dados da sessão são criptografados com AES-256-GCM usando uma chave derivada com HKDF-SHA256 (no modo FIPS, usa PBKDF2 com SHA-256).
- A sessão tem um cabeçalho de tamanho fixo protegido com HMAC-SHA256 MAC com uma chave derivada usando HKDF-SHA256 (no modo FIPS, usa PBKDF2 com SHA-256).
- Os dados da sessão podem ser armazenados em um cookie sem estado ou em vários armazenamentos de backend.
- Um único cookie de sessão pode manter várias sessões em diferentes públicos.
Nota: A versão 4.0.0 foi uma reescrita desta biblioteca com muitas lições aprendidas durante os anos. Se você ainda usa uma versão mais antiga, consulte a documentação antiga.
Sinopse
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>Iniciar o teste</a>
</body>
</html>
]])
}
}
location /start {
content_by_lua_block {
local session = require "resty.session".new()
session:set_subject("Fã do OpenResty")
session:set("quote", "A rápida raposa marrom pula sobre o cão preguiçoso")
local ok, err = session:save()
ngx.say(string.format([[
<html>
<body>
<p>Sessão iniciada (%s)</p>
<p><a href=/started>Verificar se realmente foi</a></p>
</body>
</html>
]], err or "sem erro"))
}
}
location /started {
content_by_lua_block {
local session, err = require "resty.session".start()
ngx.say(string.format([[
<html>
<body>
<p>Sessão foi iniciada por %s (%s)</p>
<p><blockquote>%s</blockquote></p>
<p><a href=/modify>Modificar a sessão</a></p>
</body>
</html>
]],
session:get_subject() or "Anônimo",
err or "sem erro",
session:get("quote") or "sem citação"
))
}
}
location /modify {
content_by_lua_block {
local session, err = require "resty.session".start()
session:set_subject("Fã de Lua")
session:set("quote", "Lorem ipsum dolor sit amet")
local _, err_save = session:save()
ngx.say(string.format([[
<html>
<body>
<p>Sessão foi modificada (%s)</p>
<p><a href=/modified>Verificar se está modificada</a></p>
</body>
</html>
]], err or err_save or "sem erro"))
}
}
location /modified {
content_by_lua_block {
local session, err = require "resty.session".start()
ngx.say(string.format([[
<html>
<body>
<p>Sessão foi iniciada por %s (%s)</p>
<p><blockquote>%s</blockquote></p>
<p><a href=/destroy>Destruir a sessão</a></p>
</body>
</html>
]],
session:get_subject() or "Anônimo",
err or "sem erro",
session:get("quote") or "sem citação"
))
}
}
location /destroy {
content_by_lua_block {
local ok, err = require "resty.session".destroy()
ngx.say(string.format([[
<html>
<body>
<p>Sessão foi destruída (%s)</p>
<p><a href=/destroyed>Verificar se realmente foi?</a></p>
</body>
</html>
]], err or "sem erro"))
}
}
location /destroyed {
content_by_lua_block {
local session, err = require "resty.session".open()
ngx.say(string.format([[
<html>
<body>
<p>A sessão foi realmente destruída, você é conhecido como %s (%s)</p>
<p><a href=/>Começar novamente</a></p>
</body>
</html>
]],
session:get_subject() or "Anônimo",
err or "sem erro"
))
}
}
}
}
Configuração
A configuração pode ser dividida em configuração genérica de sessão e configuração de armazenamento no lado do servidor.
Aqui está um exemplo:
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",
},
})
}
Configuração da Sessão
A configuração da sessão pode ser passada para funções de inicialização, construtores, e auxiliares.
Aqui estão as opções de configuração de sessão possíveis:
| Opção | Padrão | Descrição |
|---|---|---|
secret |
nil |
Segredo usado para a derivação de chave. O segredo é submetido a hash com SHA-256 antes de ser usado. Ex.: "RaJKp8UQW1". |
secret_fallbacks |
nil |
Matriz de segredos que podem ser usados como segredos alternativos (ao fazer rotação de chaves), Ex.: { "6RfrAYYzYq", "MkbTkkyF9C" }. |
ikm |
(aleatório) | O material de chaveamento inicial (ou ikm) pode ser especificado diretamente (sem usar um segredo) com exatamente 32 bytes de dados. Ex.: "5ixIW4QVMk0dPtoIhn41Eh1I9enP2060" |
ikm_fallbacks |
nil |
Matriz de materiais de chaveamento iniciais que podem ser usados como chaves alternativas (ao fazer rotação de chaves), Ex.: { "QvPtlPKxOKdP5MCu1oI3lOEXIVuDckp7" }. |
cookie_prefix |
nil |
Prefixo do cookie, use nil, "__Host-" ou "__Secure-". |
cookie_name |
"session" |
Nome do cookie de sessão, ex.: "session". |
cookie_path |
"/" |
Caminho do cookie, ex.: "/". |
cookie_domain |
nil |
Domínio do cookie, ex.: "example.com" |
cookie_http_only |
true |
Marcar cookie como somente HTTP, use true ou false. |
cookie_secure |
nil |
Marcar cookie como seguro, use nil, true ou false. |
cookie_priority |
nil |
Prioridade do cookie, use nil, "Low", "Medium" ou "High". |
cookie_same_site |
"Lax" |
Política de mesmo site do cookie, use nil, "Lax", "Strict", "None" ou "Default" |
cookie_same_party |
nil |
Marcar cookie com sinalizador de mesma parte, use nil, true ou false. |
cookie_partitioned |
nil |
Marcar cookie com sinalizador de particionado, use nil, true ou false. |
remember |
false |
Ativar ou desativar sessões persistentes, use nil, true ou false. |
remember_safety |
"Medium" |
Complexidade da derivação de chave do cookie de lembrar, use nil, "None" (rápido), "Low", "Medium", "High" ou "Very High" (lento). |
remember_cookie_name |
"remember" |
Nome do cookie de sessão persistente, ex.: "remember". |
audience |
"default" |
Público da sessão, ex.: "my-application". |
subject |
nil |
Assunto da sessão, ex.: "[email protected]". |
enforce_same_subject |
false |
Quando definido como true, os públicos precisam compartilhar o mesmo assunto. A biblioteca remove dados de público que não correspondem ao assunto ao salvar. |
stale_ttl |
10 |
Quando a sessão é salva, uma nova sessão é criada; o stale ttl especifica por quanto tempo a antiga ainda pode ser usada, ex.: 10 (em segundos). |
idling_timeout |
900 |
O tempo limite de inatividade especifica por quanto tempo a sessão pode ficar inativa até ser considerada inválida, ex.: 900 (15 minutos) (em segundos), 0 desativa as verificações e o toque. |
rolling_timeout |
3600 |
O tempo limite contínuo especifica por quanto tempo a sessão pode ser usada até precisar ser renovada, ex.: 3600 (uma hora) (em segundos), 0 desativa as verificações e a renovação contínua. |
absolute_timeout |
86400 |
O tempo limite absoluto limita por quanto tempo a sessão pode ser renovada, até que a reautenticação seja necessária, ex.: 86400 (um dia) (em segundos), 0 desativa as verificações. |
remember_rolling_timeout |
604800 |
O tempo limite de lembrar especifica por quanto tempo a sessão persistente é considerada válida, ex.: 604800 (uma semana) (em segundos), 0 desativa as verificações e a renovação contínua. |
remember_absolute_timeout |
2592000 |
O tempo limite absoluto de lembrar limita por quanto tempo a sessão persistente pode ser renovada, até que a reautenticação seja necessária, ex.: 2592000 (30 dias) (em segundos), 0 desativa as verificações. |
hash_storage_key |
false |
Se deve ou não aplicar hash à chave de armazenamento. Com a chave de armazenamento com hash, é impossível descriptografar dados no lado do servidor sem ter também um cookie, use nil, true ou false. |
hash_subject |
false |
Se deve ou não aplicar hash ao assunto quando store_metadata está ativado, ex.: por motivos de PII. |
store_metadata |
false |
Se também deve armazenar metadados de sessões, como coletar dados de sessões para um público específico pertencente a um assunto específico. |
touch_threshold |
60 |
O limite de toque controla com que frequência ou infrequência o session:refresh toca o cookie, ex.: 60 (um minuto) (em segundos) |
compression_threshold |
1024 |
O limite de compressão controla quando os dados são deflacionados, ex.: 1024 (um quilobyte) (em bytes), 0 desativa a compressão. |
bind |
nil |
Vincule a sessão a dados adquiridos da solicitação HTTP ou conexão, use ip, scheme, user-agent. Ex.: { "scheme", "user-agent" } calculará o MAC utilizando também o Scheme da solicitação HTTP e o cabeçalho User-Agent. |
request_headers |
nil |
Conjunto de cabeçalhos para enviar ao upstream, use id, audience, subject, timeout, idling-timeout, rolling-timeout, absolute-timeout. Ex.: { "id", "timeout" } definirá os cabeçalhos de solicitação Session-Id e Session-Timeout quando set_headers for chamado. |
response_headers |
nil |
Conjunto de cabeçalhos para enviar ao downstream, use id, audience, subject, timeout, idling-timeout, rolling-timeout, absolute-timeout. Ex.: { "id", "timeout" } definirá os cabeçalhos de resposta Session-Id e Session-Timeout quando set_headers for chamado. |
storage |
nil |
O armazenamento é responsável por armazenar os dados da sessão, use nil ou "cookie" (os dados são armazenados no cookie), "dshm", "file", "memcached", "mysql", "postgres", "redis" ou "shm", ou forneça um nome de módulo personalizado ("custom-storage"), ou uma table que implemente a interface de armazenamento de sessão. |
revocation |
nil |
Armazenamento usado para registros de revogação de sessão de cookie. Use nil ou false para desativar, um nome de armazenamento como "shm", "redis", "mysql" ou "postgres", um nome de módulo de armazenamento personalizado ou uma table de armazenamento com métodos set/get. |
revocation_fail_mode |
"open" |
Comportamento quando o armazenamento de revogação está inacessível, use "open" (tratar como não revogado) ou "closed" (rejeitar a sessão). |
dshm |
nil |
Configuração para armazenamento dshm, ex.: { prefix = "sessions" } (veja abaixo) |
file |
nil |
Configuração para armazenamento de arquivo, ex.: { path = "/tmp", suffix = "session" } (veja abaixo) |
memcached |
nil |
Configuração para armazenamento memcached, ex.: { prefix = "sessions" } (veja abaixo) |
mysql |
nil |
Configuração para armazenamento MySQL / MariaDB, ex.: { database = "sessions" } (veja abaixo) |
postgres |
nil |
Configuração para armazenamento Postgres, ex.: { database = "sessions" } (veja abaixo) |
redis |
nil |
Configuração para armazenamentos Redis / Redis Sentinel / Redis Cluster, ex.: { prefix = "sessions" } (veja abaixo) |
shm |
nil |
Configuração para armazenamento de memória compartilhada, ex.: { zone = "sessions" } |
["custom-storage"] |
nil |
Configuração de armazenamento personalizado (carregado com require "custom-storage"). |
Configuração de Armazenamento de Cookie
Ao armazenar dados em cookie, nenhuma configuração adicional é necessária;
basta definir o storage como nil ou "cookie".
Configuração de Revogação de Sessão
Sessões de cookie (sem estado) são autocontidas: uma vez emitidas, um cookie permanece válido até expirar de acordo com os tempos limite configurados. A revogação adiciona uma lista de negação opcional baseada em armazenamento para que sessões destruídas sejam rejeitadas imediatamente, sem esperar a expiração do cookie.
A revogação só está disponível quando os dados da sessão são armazenados no cookie
(storage é nil ou "cookie"). Selecione o backend explicitamente com
revocation = "dshm", "file", "memcached", "mysql", "postgres",
"redis" ou "shm". O backend usa sua seção de configuração normal e
o mesmo contrato de armazenamento set/get usado para dados de sessão. Nomes de módulos
de armazenamento personalizados e tabelas de armazenamento pré-construídas também são suportados. Definir
revocation = false ou deixá-lo não definido desativa a revogação.
Em cada session:open, a biblioteca verifica se o identificador da sessão está
revogado. Em session:destroy, o identificador é gravado no
armazenamento selecionado com um TTL igual ao tempo de vida restante da sessão (tempos limite
contínuo e absoluto). A marca de revogação é um sentinela leve; nenhum
payload de sessão é armazenado.
Use revocation_fail_mode para controlar o comportamento quando o armazenamento está indisponível:
"open"(padrão): registra um aviso e trata a sessão como não revogada. A destruição ainda limpa o cookie mesmo se a gravação de revogação falhar."closed": rejeita a operação de abertura ou destruição da sessão.
A revogação se aplica a session:destroy (e session:logout quando destrói
o último público). Ela não revoga o identificador de sessão anterior em
session:save (rotação de sessão) ou session:logout parcial (múltiplos
públicos). Após rotação ou logout parcial, o cookie anterior permanece
utilizável até que seu stale_ttl ou tempo limite expire.
Exemplos:
-- Lista de negação Redis
require("resty.session").init({
storage = "cookie",
revocation = "redis",
redis = {
host = "127.0.0.1",
password = "secret",
prefix = "sessions",
},
})
-- Lista de negação de memória compartilhada
require("resty.session").init({
storage = "cookie",
revocation = "shm",
shm = {
zone = "sessions",
prefix = "revocations",
},
})
-- Lista de negação MySQL
require("resty.session").init({
storage = "cookie",
revocation = "mysql",
mysql = {
host = "127.0.0.1",
database = "sessions",
username = "session",
password = "secret",
},
})
O mesmo padrão funciona para "dshm", "file", "memcached" e "postgres".
Configuração de Armazenamento DSHM
Com o armazenamento DHSM, você pode usar as seguintes configurações (defina o storage como "dshm"):
| Opção | Padrão | Descrição |
|---|---|---|
prefix |
nil |
O prefixo para as chaves armazenadas no DSHM. |
suffix |
nil |
O sufixo para as chaves armazenadas no DSHM. |
host |
"127.0.0.1" |
O host para conectar. |
port |
4321 |
A porta para conectar. |
connect_timeout |
nil |
Controla o valor de tempo limite padrão usado no método connect do objeto de socket TCP/domínio unix. |
send_timeout |
nil |
Controla o valor de tempo limite padrão usado no método send do objeto de socket TCP/domínio unix. |
read_timeout |
nil |
Controla o valor de tempo limite padrão usado no método receive do objeto de socket TCP/domínio unix. |
keepalive_timeout |
nil |
Controla o tempo máximo de inatividade padrão das conexões no pool de conexões. |
pool |
nil |
Um nome personalizado para o pool de conexões usado. |
pool_size |
nil |
O tamanho do pool de conexões. |
backlog |
nil |
Um tamanho de fila a ser usado quando o pool de conexões está cheio (configurado com pool_size). |
ssl |
nil |
Ativar SSL. |
ssl_verify |
nil |
Verificar certificado do servidor. |
server_name |
nil |
O nome do servidor para a nova extensão TLS Server Name Indication (SNI). |
Consulte ngx-distributed-shm para obter as dependências necessárias instaladas.
Configuração de Armazenamento de Arquivo
Com o armazenamento de arquivo, você pode usar as seguintes configurações (defina o storage como "file"):
| Opção | Padrão | Descrição |
|---|---|---|
prefix |
nil |
Prefixo do arquivo para o arquivo de sessão. |
suffix |
nil |
Sufixo do arquivo (ou extensão sem .) para o arquivo de sessão. |
pool |
nil |
Nome do pool de threads sob o qual a gravação de arquivo acontece (disponível apenas no Linux). |
path |
(diretório tmp) | Caminho (ou diretório) sob o qual os arquivos de sessão são criados. |
A implementação requer LuaFileSystem que você pode instalar com LuaRocks:
❯ luarocks install LuaFileSystem
Configuração de Armazenamento Memcached
Com o Memcached de arquivo, você pode usar as seguintes configurações (defina o storage como "memcached"):
| Opção | Padrão | Descrição |
|---|---|---|
prefix |
nil |
Prefixo para as chaves armazenadas no memcached. |
suffix |
nil |
Sufixo para as chaves armazenadas no memcached. |
host |
127.0.0.1 |
O host para conectar. |
port |
11211 |
A porta para conectar. |
socket |
nil |
O arquivo de socket para conectar. |
connect_timeout |
nil |
Controla o valor de tempo limite padrão usado no método connect do objeto de socket TCP/domínio unix. |
send_timeout |
nil |
Controla o valor de tempo limite padrão usado no método send do objeto de socket TCP/domínio unix. |
read_timeout |
nil |
Controla o valor de tempo limite padrão usado no método receive do objeto de socket TCP/domínio unix. |
keepalive_timeout |
nil |
Controla o tempo máximo de inatividade padrão das conexões no pool de conexões. |
pool |
nil |
Um nome personalizado para o pool de conexões usado. |
pool_size |
nil |
O tamanho do pool de conexões. |
backlog |
nil |
Um tamanho de fila a ser usado quando o pool de conexões está cheio (configurado com pool_size). |
ssl |
false |
Ativar SSL |
ssl_verify |
nil |
Verificar certificado do servidor |
server_name |
nil |
O nome do servidor para a nova extensão TLS Server Name Indication (SNI). |
Configuração de Armazenamento MySQL / MariaDB
Com o MySQL / MariaDB de arquivo, você pode usar as seguintes configurações (defina o storage como "mysql"):
| Opção | Padrão | Descrição |
|---|---|---|
host |
"127.0.0.1" |
O host para conectar. |
port |
3306 |
A porta para conectar. |
socket |
nil |
O arquivo de socket para conectar. |
username |
nil |
O nome de usuário do banco de dados para autenticar. |
password |
nil |
Senha para autenticação, pode ser necessária dependendo da configuração do servidor. |
charset |
"ascii" |
O conjunto de caracteres usado na conexão MySQL. |
database |
nil |
O nome do banco de dados para conectar. |
table_name |
"sessions" |
Nome da tabela do banco de dados na qual armazenar os dados da sessão. |
table_name_meta |
"sessions_meta" |
Nome da tabela de metadados do banco de dados na qual armazenar os metadados da sessão. |
max_packet_size |
1048576 |
O limite superior para os pacotes de resposta enviados pelo servidor MySQL (em bytes). |
connect_timeout |
nil |
Controla o valor de tempo limite padrão usado no método connect do objeto de socket TCP/domínio unix. |
send_timeout |
nil |
Controla o valor de tempo limite padrão usado no método send do objeto de socket TCP/domínio unix. |
read_timeout |
nil |
Controla o valor de tempo limite padrão usado no método receive do objeto de socket TCP/domínio unix. |
keepalive_timeout |
nil |
Controla o tempo máximo de inatividade padrão das conexões no pool de conexões. |
pool |
nil |
Um nome personalizado para o pool de conexões usado. |
pool_size |
nil |
O tamanho do pool de conexões. |
backlog |
nil |
Um tamanho de fila a ser usado quando o pool de conexões está cheio (configurado com pool_size). |
ssl |
false |
Ativar SSL. |
ssl_verify |
nil |
Verificar certificado do servidor. |
Você também precisa criar as seguintes tabelas em seu banco de dados:
--
-- Tabela do banco de dados que armazena os dados da sessão.
--
CREATE TABLE IF NOT EXISTS sessions (
sid CHAR(43) PRIMARY KEY,
name VARCHAR(255),
data MEDIUMTEXT,
exp DATETIME,
INDEX (exp)
) CHARACTER SET ascii;
--
-- Tabela de metadados de sessões.
--
-- Isso só é necessário se você quiser armazenar metadados de sessão.
--
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;
Configuração do Postgres
Com o Postgres de arquivo, você pode usar as seguintes configurações (defina o storage como "postgres"):
| Opção | Padrão | Descrição |
|---|---|---|
host |
"127.0.0.1" |
O host para conectar. |
port |
5432 |
A porta para conectar. |
application |
5432 |
Define o nome da conexão como exibido em pg_stat_activity (padrão é "pgmoon"). |
username |
"postgres" |
O nome de usuário do banco de dados para autenticar. |
password |
nil |
Senha para autenticação, pode ser necessária dependendo da configuração do servidor. |
database |
nil |
O nome do banco de dados para conectar. |
table_name |
"sessions" |
Nome da tabela do banco de dados na qual armazenar os dados da sessão (pode ser prefixado com esquema do banco de dados). |
table_name_meta |
"sessions_meta" |
Nome da tabela de metadados do banco de dados na qual armazenar os metadados da sessão (pode ser prefixado com esquema do banco de dados). |
connect_timeout |
nil |
Controla o valor de tempo limite padrão usado no método connect do objeto de socket TCP/domínio unix. |
send_timeout |
nil |
Controla o valor de tempo limite padrão usado no método send do objeto de socket TCP/domínio unix. |
read_timeout |
nil |
Controla o valor de tempo limite padrão usado no método receive do objeto de socket TCP/domínio unix. |
keepalive_timeout |
nil |
Controla o tempo máximo de inatividade padrão das conexões no pool de conexões. |
pool |
nil |
Um nome personalizado para o pool de conexões usado. |
pool_size |
nil |
O tamanho do pool de conexões. |
backlog |
nil |
Um tamanho de fila a ser usado quando o pool de conexões está cheio (configurado com pool_size). |
ssl |
false |
Ativar SSL. |
ssl_verify |
nil |
Verificar certificado do servidor. |
ssl_required |
nil |
Abortar a conexão se o servidor não suportar conexões SSL. |
Você também precisa criar as seguintes tabelas em seu banco