session : Bibliothèque de sessions pour nginx-module-lua – flexible et sécurisée
Installation
Si vous n'avez pas encore configuré l'abonnement au dépôt RPM, inscrivez-vous. Vous pouvez ensuite procéder aux étapes suivantes.
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
Pour utiliser cette bibliothèque Lua avec NGINX, assurez-vous que nginx-module-lua est installé.
Ce document décrit lua-resty-session v4.2.0 publiée le 24 août 2026.
lua-resty-session est une bibliothèque de sessions sécurisée et flexible pour OpenResty.
TL;DR;
- Les sessions sont immuables (chaque sauvegarde génère une nouvelle session) et sans verrou.
- Les données de session sont chiffrées avec AES-256-GCM en utilisant une clé dérivée avec HKDF-SHA256 (en mode FIPS, PBKDF2 avec SHA-256 est utilisé à la place).
- La session possède un en-tête de taille fixe protégé par HMAC-SHA256 MAC avec une clé dérivée avec HKDF-SHA256 (en mode FIPS, PBKDF2 avec SHA-256 est utilisé à la place).
- Les données de session peuvent être stockées dans un cookie sans état ou dans divers stockages backend.
- Un seul cookie de session peut maintenir plusieurs sessions pour différentes audiences.
Note : La version 4.0.0 était une réécriture de cette bibliothèque avec beaucoup de leçons apprises au fil des années. Si vous utilisez encore une version plus ancienne, veuillez consulter l'ancienne documentation.
Synopsis
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"
))
}
}
}
}
Configuration
La configuration peut être divisée en configuration générique de session et configuration du stockage côté serveur.
Voici un exemple :
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",
},
})
}
Configuration de session
La configuration de session peut être transmise aux fonctions d'initialisation, de construction, et auxiliaires.
Voici les options de configuration de session possibles :
| Option | Défaut | Description |
|---|---|---|
secret |
nil |
Secret utilisé pour la dérivation de clé. Le secret est haché avec SHA-256 avant utilisation. Par exemple "RaJKp8UQW1". |
secret_fallbacks |
nil |
Tableau de secrets pouvant être utilisés comme secrets alternatifs (lors de la rotation des clés), par exemple { "6RfrAYYzYq", "MkbTkkyF9C" }. |
ikm |
(aléatoire) | Le matériau de clé initial (ou ikm) peut être spécifié directement (sans utiliser un secret) avec exactement 32 octets de données. Par exemple "5ixIW4QVMk0dPtoIhn41Eh1I9enP2060" |
ikm_fallbacks |
nil |
Tableau de matériaux de clé initiaux pouvant être utilisés comme clés alternatives (lors de la rotation des clés), par exemple { "QvPtlPKxOKdP5MCu1oI3lOEXIVuDckp7" }. |
cookie_prefix |
nil |
Préfixe du cookie, utilisez nil, "__Host-" ou "__Secure-". |
cookie_name |
"session" |
Nom du cookie de session, par exemple "session". |
cookie_path |
"/" |
Chemin du cookie, par exemple "/". |
cookie_domain |
nil |
Domaine du cookie, par exemple "example.com" |
cookie_http_only |
true |
Marquer le cookie comme HTTP uniquement, utilisez true ou false. |
cookie_secure |
nil |
Marquer le cookie comme sécurisé, utilisez nil, true ou false. |
cookie_priority |
nil |
Priorité du cookie, utilisez nil, "Low", "Medium" ou "High". |
cookie_same_site |
"Lax" |
Politique same-site du cookie, utilisez nil, "Lax", "Strict", "None" ou "Default" |
cookie_same_party |
nil |
Marquer le cookie avec l'indicateur same party, utilisez nil, true ou false. |
cookie_partitioned |
nil |
Marquer le cookie avec l'indicateur partitioned, utilisez nil, true ou false. |
remember |
false |
Activer ou désactiver les sessions persistantes, utilisez nil, true ou false. |
remember_safety |
"Medium" |
Complexité de dérivation de clé du cookie remember, utilisez nil, "None" (rapide), "Low", "Medium", "High" ou "Very High" (lent). |
remember_cookie_name |
"remember" |
Nom du cookie de session persistant, par exemple "remember". |
audience |
"default" |
Audience de la session, par exemple "my-application". |
subject |
nil |
Sujet de la session, par exemple "[email protected]". |
enforce_same_subject |
false |
Lorsqu'il est défini sur true, les audiences doivent partager le même sujet. La bibliothèque supprime les données d'audience ne correspondant pas au sujet lors de la sauvegarde. |
stale_ttl |
10 |
Lorsqu'une session est sauvegardée, une nouvelle session est créée ; le stale ttl spécifie combien de temps l'ancienne peut encore être utilisée, par exemple 10 (en secondes). |
idling_timeout |
900 |
Le délai d'inactivité spécifie combien de temps la session peut être inactive avant d'être considérée comme invalide, par exemple 900 (15 minutes) (en secondes), 0 désactive les vérifications et le touch. |
rolling_timeout |
3600 |
Le délai glissant spécifie combien de temps la session peut être utilisée avant de devoir être renouvelée, par exemple 3600 (une heure) (en secondes), 0 désactive les vérifications et le rolling. |
absolute_timeout |
86400 |
Le délai absolu limite la durée pendant laquelle la session peut être renouvelée, jusqu'à ce qu'une ré-authentification soit requise, par exemple 86400 (un jour) (en secondes), 0 désactive les vérifications. |
remember_rolling_timeout |
604800 |
Le délai remember spécifie combien de temps la session persistante est considérée comme valide, par exemple 604800 (une semaine) (en secondes), 0 désactive les vérifications et le rolling. |
remember_absolute_timeout |
2592000 |
Le délai absolu remember limite la durée pendant laquelle la session persistante peut être renouvelée, jusqu'à ce qu'une ré-authentification soit requise, par exemple 2592000 (30 jours) (en secondes), 0 désactive les vérifications. |
hash_storage_key |
false |
Indique s'il faut hacher ou non la clé de stockage. Avec une clé de stockage hachée, il est impossible de déchiffrer les données côté serveur sans avoir aussi un cookie, utilisez nil, true ou false. |
hash_subject |
false |
Indique s'il faut hacher ou non le sujet lorsque store_metadata est activé, par exemple pour des raisons de PII. |
store_metadata |
false |
Indique s'il faut également stocker les métadonnées des sessions, comme la collecte de données de sessions pour une audience spécifique appartenant à un sujet spécifique. |
touch_threshold |
60 |
Le seuil de touch contrôle la fréquence à laquelle session:refresh touche le cookie, par exemple 60 (une minute) (en secondes) |
compression_threshold |
1024 |
Le seuil de compression contrôle quand les données sont déflatées, par exemple 1024 (un kilooctet) (en octets), 0 désactive la compression. |
bind |
nil |
Lier la session aux données acquises depuis la requête HTTP ou la connexion, utilisez ip, scheme, user-agent. Par exemple { "scheme", "user-agent" } calculera le MAC en utilisant également le Scheme de la requête HTTP et l'en-tête User-Agent. |
request_headers |
nil |
Ensemble d'en-têtes à envoyer en amont, utilisez id, audience, subject, timeout, idling-timeout, rolling-timeout, absolute-timeout. Par exemple { "id", "timeout" } définira les en-têtes de requête Session-Id et Session-Timeout lorsque set_headers est appelé. |
response_headers |
nil |
Ensemble d'en-têtes à envoyer en aval, utilisez id, audience, subject, timeout, idling-timeout, rolling-timeout, absolute-timeout. Par exemple { "id", "timeout" } définira les en-têtes de réponse Session-Id et Session-Timeout lorsque set_headers est appelé. |
storage |
nil |
Le stockage est responsable du stockage des données de session, utilisez nil ou "cookie" (les données sont stockées dans le cookie), "dshm", "file", "memcached", "mysql", "postgres", "redis" ou "shm", ou donnez un nom de module personnalisé ("custom-storage"), ou une table qui implémente l'interface de stockage de session. |
revocation |
nil |
Stockage utilisé pour les enregistrements de révocation de session par cookie. Utilisez nil ou false pour désactiver, un nom de stockage tel que "shm", "redis", "mysql" ou "postgres", un nom de module de stockage personnalisé, ou une table de stockage avec des méthodes set/get. |
revocation_fail_mode |
"open" |
Comportement lorsque le magasin de révocation est inaccessible, utilisez "open" (considérer comme non révoqué) ou "closed" (rejeter la session). |
dshm |
nil |
Configuration pour le stockage dshm, par exemple { prefix = "sessions" } (voir ci-dessous) |
file |
nil |
Configuration pour le stockage par fichier, par exemple { path = "/tmp", suffix = "session" } (voir ci-dessous) |
memcached |
nil |
Configuration pour le stockage memcached, par exemple { prefix = "sessions" } (voir ci-dessous) |
mysql |
nil |
Configuration pour le stockage MySQL / MariaDB, par exemple { database = "sessions" } (voir ci-dessous) |
postgres |
nil |
Configuration pour le stockage Postgres, par exemple { database = "sessions" } (voir ci-dessous) |
redis |
nil |
Configuration pour les stockages Redis / Redis Sentinel / Redis Cluster, par exemple { prefix = "sessions" } (voir ci-dessous) |
shm |
nil |
Configuration pour le stockage en mémoire partagée, par exemple { zone = "sessions" } |
["custom-storage"] |
nil |
Configuration du stockage personnalisé (chargé avec require "custom-storage"). |
Configuration du stockage par cookie
Lors du stockage des données dans un cookie, aucune configuration supplémentaire n'est requise,
il suffit de définir storage sur nil ou "cookie".
Configuration de la révocation de session
Les sessions par cookie (sans état) sont autonomes : une fois émises, un cookie reste valide jusqu'à son expiration selon les délais configurés. La révocation ajoute une liste de blocage optionnelle adossée à un stockage afin que les sessions détruites soient rejetées immédiatement, sans attendre l'expiration du cookie.
La révocation n'est disponible que lorsque les données de session sont stockées dans le cookie
(storage est nil ou "cookie"). Sélectionnez explicitement le backend avec
revocation = "dshm", "file", "memcached", "mysql", "postgres",
"redis" ou "shm". Le backend utilise sa section de configuration normale et
le même contrat de stockage set/get utilisé pour les données de session. Les noms
de modules de stockage personnalisés et les tables de stockage pré-construites sont également pris en charge. Définir
revocation = false ou le laisser non défini désactive la révocation.
À chaque session:open, la bibliothèque vérifie si l'identifiant de session est
révoqué. Lors de session:destroy, l'identifiant est écrit dans le stockage
sélectionné avec un TTL égal à la durée de vie restante de la session (délais glissant et
absolu). La marque de révocation est un sentinelle léger ; aucune charge utile de session
n'est stockée.
Utilisez revocation_fail_mode pour contrôler le comportement lorsque le stockage est indisponible :
"open"(défaut) : journaliser un avertissement et considérer la session comme non révoquée. La destruction efface toujours le cookie même si l'écriture de révocation échoue."closed": rejeter l'opération d'ouverture ou de destruction de session.
La révocation s'applique à session:destroy (et session:logout lorsqu'elle détruit
la dernière audience). Elle ne révoque pas l'identifiant de session précédent lors de
session:save (rotation de session) ou d'un session:logout partiel (plusieurs
audiences). Après une rotation ou une déconnexion partielle, le cookie précédent reste
utilisable jusqu'à l'expiration de son stale_ttl ou de ses délais.
Exemples :
-- Liste de blocage Redis
require("resty.session").init({
storage = "cookie",
revocation = "redis",
redis = {
host = "127.0.0.1",
password = "secret",
prefix = "sessions",
},
})
-- Liste de blocage en mémoire partagée
require("resty.session").init({
storage = "cookie",
revocation = "shm",
shm = {
zone = "sessions",
prefix = "revocations",
},
})
-- Liste de blocage MySQL
require("resty.session").init({
storage = "cookie",
revocation = "mysql",
mysql = {
host = "127.0.0.1",
database = "sessions",
username = "session",
password = "secret",
},
})
Le même modèle fonctionne pour "dshm", "file", "memcached" et "postgres".
Configuration du stockage DSHM
Avec le stockage DSHM, vous pouvez utiliser les paramètres suivants (définissez storage sur "dshm") :
| Option | Défaut | Description |
|---|---|---|
prefix |
nil |
Le préfixe pour les clés stockées dans DSHM. |
suffix |
nil |
Le suffixe pour les clés stockées dans DSHM. |
host |
"127.0.0.1" |
L'hôte auquel se connecter. |
port |
4321 |
Le port auquel se connecter. |
connect_timeout |
nil |
Contrôle la valeur de délai d'attente par défaut utilisée dans la méthode connect de l'objet socket TCP/domaine Unix. |
send_timeout |
nil |
Contrôle la valeur de délai d'attente par défaut utilisée dans la méthode send de l'objet socket TCP/domaine Unix. |
read_timeout |
nil |
Contrôle la valeur de délai d'attente par défaut utilisée dans la méthode receive de l'objet socket TCP/domaine Unix. |
keepalive_timeout |
nil |
Contrôle le temps d'inactivité maximal par défaut des connexions dans le pool de connexions. |
pool |
nil |
Un nom personnalisé pour le pool de connexions utilisé. |
pool_size |
nil |
La taille du pool de connexions. |
backlog |
nil |
Une taille de file d'attente à utiliser lorsque le pool de connexions est plein (configuré avec pool_size). |
ssl |
nil |
Activer SSL. |
ssl_verify |
nil |
Vérifier le certificat du serveur. |
server_name |
nil |
Le nom du serveur pour la nouvelle extension TLS Server Name Indication (SNI). |
Veuillez vous référer à ngx-distributed-shm pour installer les dépendances nécessaires.
Configuration du stockage par fichier
Avec le stockage par fichier, vous pouvez utiliser les paramètres suivants (définissez storage sur "file") :
| Option | Défaut | Description |
|---|---|---|
prefix |
nil |
Préfixe de fichier pour le fichier de session. |
suffix |
nil |
Suffixe de fichier (ou extension sans .) pour le fichier de session. |
pool |
nil |
Nom du pool de threads sous lequel l'écriture de fichier se produit (disponible sur Linux uniquement). |
path |
(répertoire temporaire) | Chemin (ou répertoire) sous lequel les fichiers de session sont créés. |
L'implémentation nécessite LuaFileSystem que vous pouvez installer avec LuaRocks :
❯ luarocks install LuaFileSystem
Configuration du stockage Memcached
Avec le stockage Memcached, vous pouvez utiliser les paramètres suivants (définissez storage sur "memcached") :
| Option | Défaut | Description |
|---|---|---|
prefix |
nil |
Préfixe pour les clés stockées dans memcached. |
suffix |
nil |
Suffixe pour les clés stockées dans memcached. |
host |
127.0.0.1 |
L'hôte auquel se connecter. |
port |
11211 |
Le port auquel se connecter. |
socket |
nil |
Le fichier socket auquel se connecter. |
connect_timeout |
nil |
Contrôle la valeur de délai d'attente par défaut utilisée dans la méthode connect de l'objet socket TCP/domaine Unix. |
send_timeout |
nil |
Contrôle la valeur de délai d'attente par défaut utilisée dans la méthode send de l'objet socket TCP/domaine Unix. |
read_timeout |
nil |
Contrôle la valeur de délai d'attente par défaut utilisée dans la méthode receive de l'objet socket TCP/domaine Unix. |
keepalive_timeout |
nil |
Contrôle le temps d'inactivité maximal par défaut des connexions dans le pool de connexions. |
pool |
nil |
Un nom personnalisé pour le pool de connexions utilisé. |
pool_size |
nil |
La taille du pool de connexions. |
backlog |
nil |
Une taille de file d'attente à utiliser lorsque le pool de connexions est plein (configuré avec pool_size). |
ssl |
false |
Activer SSL |
ssl_verify |
nil |
Vérifier le certificat du serveur |
server_name |
nil |
Le nom du serveur pour la nouvelle extension TLS Server Name Indication (SNI). |
Configuration du stockage MySQL / MariaDB
Avec le stockage MySQL / MariaDB, vous pouvez utiliser les paramètres suivants (définissez storage sur "mysql") :
| Option | Défaut | Description |
|---|---|---|
host |
"127.0.0.1" |
L'hôte auquel se connecter. |
port |
3306 |
Le port auquel se connecter. |
socket |
nil |
Le fichier socket auquel se connecter. |
username |
nil |
Le nom d'utilisateur de la base de données pour l'authentification. |
password |
nil |
Mot de passe pour l'authentification, peut être requis selon la configuration du serveur. |
charset |
"ascii" |
Le jeu de caractères utilisé sur la connexion MySQL. |
database |
nil |
Le nom de la base de données à laquelle se connecter. |
table_name |
"sessions" |
Nom de la table de base de données dans laquelle stocker les données de session. |
table_name_meta |
"sessions_meta" |
Nom de la table de métadonnées de base de données dans laquelle stocker les métadonnées de session. |
max_packet_size |
1048576 |
La limite supérieure pour les paquets de réponse envoyés par le serveur MySQL (en octets). |
connect_timeout |
nil |
Contrôle la valeur de délai d'attente par défaut utilisée dans la méthode connect de l'objet socket TCP/domaine Unix. |
send_timeout |
nil |
Contrôle la valeur de délai d'attente par défaut utilisée dans la méthode send de l'objet socket TCP/domaine Unix. |
read_timeout |
nil |
Contrôle la valeur de délai d'attente par défaut utilisée dans la méthode receive de l'objet socket TCP/domaine Unix. |
keepalive_timeout |
nil |
Contrôle le temps d'inactivité maximal par défaut des connexions dans le pool de connexions. |
pool |
nil |
Un nom personnalisé pour le pool de connexions utilisé. |
pool_size |
nil |
La taille du pool de connexions. |
backlog |
nil |
Une taille de file d'attente à utiliser lorsque le pool de connexions est plein (configuré avec pool_size). |
ssl |
false |
Activer SSL. |
ssl_verify |
nil |
Vérifier le certificat du serveur. |
Vous devez également créer les tables suivantes dans votre base de données :
--
-- Table de base de données qui stocke les données de session.
--
CREATE TABLE IF NOT EXISTS sessions (
sid CHAR(43) PRIMARY KEY,
name VARCHAR(255),
data MEDIUMTEXT,
exp DATETIME,
INDEX (exp)
) CHARACTER SET ascii;
--
-- Table de métadonnées de sessions.
--
-- Ceci n'est nécessaire que si vous souhaitez stocker les métadonnées de session.
--
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;
Configuration Postgres
Avec le stockage Postgres, vous pouvez utiliser les paramètres suivants (définissez storage sur "postgres") :
| Option | Défaut | Description |
|---|---|---|
host |
"127.0.0.1" |
L'hôte auquel se connecter. |
port |
5432 |
Le port auquel se connecter. |
application |
5432 |
Définir le nom de la connexion tel qu'affiché dans pg_stat_activity (par défaut "pgmoon"). |
username |
"postgres" |
Le nom d'utilisateur de la base de données pour l'authentification. |
password |
nil |
Mot de passe pour l'authentification, peut être requis selon la configuration du serveur. |
database |
nil |
Le nom de la base de données à laquelle se connecter. |
table_name |
"sessions" |
Nom de la table de base de données dans laquelle stocker les données de session (peut être préfixé par schéma de base de données). |
table_name_meta |
"sessions_meta" |
Nom de la table de métadonnées de base de données dans laquelle stocker les métadonnées de session (peut être préfixé par schéma de base de données). |
connect_timeout |
nil |
Contrôle la valeur de délai d'attente par défaut utilisée dans la méthode connect de l'objet socket TCP/domaine Unix. |
send_timeout |
nil |
Contrôle la valeur de délai d'attente par défaut utilisée dans la méthode send de l'objet socket TCP/domaine Unix. |
read_timeout |
nil |
Contrôle la valeur de délai d'attente par défaut utilisée dans la méthode receive de l'objet socket TCP/domaine Unix. |
keepalive_timeout |
nil |
Contrôle le temps d'inactivité maximal par défaut des connexions dans le pool de connexions. |
pool |
nil |
Un nom personnalisé pour le pool de connexions utilisé. |
pool_size |
nil |
La taille du pool de connexions. |
backlog |
nil |
Une taille de file d'attente à utiliser lorsque le pool de connexions est plein (configuré avec pool_size). |
ssl |
false |
Activer SSL. |
ssl_verify |
nil |
Vérifier le certificat du serveur. |
ssl_required |
nil |
Abandonner la connexion si le serveur ne prend pas en charge les |