Aller au contenu

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").

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