Zum Inhalt

session: Sitzungsbibliothek für nginx-module-lua – flexibel und sicher

Installation

Wenn Sie das RPM-Repository-Abonnement noch nicht eingerichtet haben, melden Sie sich an. Danach können Sie mit den folgenden Schritten fortfahren.

CentOS/RHEL 7 oder 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

Um diese Lua-Bibliothek mit NGINX zu verwenden, stellen Sie sicher, dass nginx-module-lua installiert ist.

Dieses Dokument beschreibt lua-resty-session v4.1.5, veröffentlicht am 24. November 2025.


lua-resty-session ist eine sichere und flexible Sitzungsbibliothek für OpenResty.

TL;DR;

  • Sitzungen sind unveränderlich (jeder Speichervorgang erzeugt eine neue Sitzung) und ohne Sperren.
  • Sitzungsdaten sind mit AES-256-GCM verschlüsselt, wobei ein Schlüssel verwendet wird, der mit HKDF-SHA256 abgeleitet wurde (im FIPS-Modus wird stattdessen PBKDF2 mit SHA-256 verwendet).
  • Die Sitzung hat einen festen Header, der mit HMAC-SHA256 MAC geschützt ist, wobei ein Schlüssel verwendet wird, der mit HKDF-SHA256 abgeleitet wurde (im FIPS-Modus wird stattdessen PBKDF2 mit SHA-256 verwendet).
  • Sitzungsdaten können in einem zustandslosen Cookie oder in verschiedenen Backend-Speichern gespeichert werden.
  • Ein einzelnes Sitzungscookie kann mehrere Sitzungen über verschiedene Zielgruppen hinweg verwalten.

Hinweis: Version 4.0.0 war eine Neuschreibung dieser Bibliothek mit vielen Erkenntnissen aus den Jahren. Wenn Sie noch eine ältere Version verwenden, beziehen Sie sich bitte auf die alte Dokumentation.

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", "Der schnelle braune Fuchs springt über den faulen Hund")
        local ok, err = session:save()

        ngx.say(string.format([[
          <html>
          <body>
            <p>Sitzung gestartet (%s)</p>
            <p><a href=/started>Überprüfen Sie, ob es wirklich so war</a></p>
          </body>
          </html>
        ]], err or "kein Fehler"))
      }
    }

    location /started {
      content_by_lua_block {
        local session, err = require "resty.session".start()

        ngx.say(string.format([[
          <html>
          <body>
            <p>Sitzung wurde gestartet von %s (%s)</p>
            <p><blockquote>%s</blockquote></p>
            <p><a href=/modify>Sitzung ändern</a></p>
          </body>
          </html>
        ]],
          session:get_subject() or "Anonym",
          err or "kein Fehler",
          session:get("quote") or "kein Zitat"
        ))
      }
    }

    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>Sitzung wurde geändert (%s)</p>
            <p><a href=/modified>Überprüfen Sie, ob sie geändert wurde</a></p>
          </body>
          </html>
        ]], err or err_save or "kein Fehler"))
      }
    }

    location /modified {
      content_by_lua_block {
        local session, err = require "resty.session".start()

        ngx.say(string.format([[
          <html>
          <body>
            <p>Sitzung wurde gestartet von %s (%s)</p>
            <p><blockquote>%s</blockquote></p>
            <p><a href=/destroy>Sitzung zerstören</a></p>
          </body>
          </html>
        ]],
          session:get_subject() or "Anonym",
          err or "kein Fehler",
          session:get("quote")  or "kein Zitat"
        ))
      }
    }

    location /destroy {
      content_by_lua_block {
        local ok, err = require "resty.session".destroy()

        ngx.say(string.format([[
          <html>
          <body>
            <p>Sitzung wurde zerstört (%s)</p>
            <p><a href=/destroyed>Überprüfen Sie, ob es wirklich so war?</a></p>
          </body>
          </html>
        ]], err or "kein Fehler"))
      }
    }

    location /destroyed {
      content_by_lua_block {
        local session, err = require "resty.session".open()

        ngx.say(string.format([[
          <html>
          <body>
            <p>Sitzung wurde wirklich zerstört, Sie sind bekannt als %s (%s)</p>
            <p><a href=/>Erneut starten</a></p>
          </body>
          </html>
        ]],
          session:get_subject() or "Anonym",
          err or "kein Fehler"
        ))
      }
    }
  }
}

Konfiguration

Die Konfiguration kann in allgemeine Sitzungs- und serverseitige Speicherkonfiguration unterteilt werden.

Hier ist ein Beispiel:

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",
    },
  })
}

Sitzungs-Konfiguration

Die Sitzungs-Konfiguration kann an die Initialisierung, Konstruktor und Hilfsfunktionen übergeben werden.

Hier sind die möglichen Optionen für die Sitzungs-Konfiguration:

Option Standard Beschreibung
secret nil Geheimnis, das für die Schlüsselableitung verwendet wird. Das Geheimnis wird vor der Verwendung mit SHA-256 gehasht. Z.B. "RaJKp8UQW1".
secret_fallbacks nil Array von Geheimnissen, die als alternative Geheimnisse verwendet werden können (bei Schlüsselrotation), z.B. { "6RfrAYYzYq", "MkbTkkyF9C" }.
ikm (zufällig) Initiales Schlüsselmaterial (oder ikm) kann direkt (ohne Verwendung eines Geheimnisses) mit genau 32 Bytes Daten angegeben werden. Z.B. "5ixIW4QVMk0dPtoIhn41Eh1I9enP2060"
ikm_fallbacks nil Array von initialen Schlüsselmaterialien, die als alternative Schlüssel verwendet werden können (bei Schlüsselrotation), z.B. { "QvPtlPKxOKdP5MCu1oI3lOEXIVuDckp7" }.
cookie_prefix nil Cookie-Präfix, verwenden Sie nil, "__Host-" oder "__Secure-".
cookie_name "session" Name des Sitzungscookies, z.B. "session".
cookie_path "/" Cookie-Pfad, z.B. "/".
cookie_domain nil Cookie-Domain, z.B. "example.com"
cookie_http_only true Cookie als HTTP-only markieren, verwenden Sie true oder false.
cookie_secure nil Cookie als sicher markieren, verwenden Sie nil, true oder false.
cookie_priority nil Cookie-Priorität, verwenden Sie nil, "Low", "Medium" oder "High".
cookie_same_site "Lax" Cookie Same-Site-Richtlinie, verwenden Sie nil, "Lax", "Strict", "None" oder "Default"
cookie_same_party nil Cookie mit Same-Party-Flag markieren, verwenden Sie nil, true oder false.
cookie_partitioned nil Cookie mit partitioniertem Flag markieren, verwenden Sie nil, true oder false.
remember false Persistente Sitzungen aktivieren oder deaktivieren, verwenden Sie nil, true oder false.
remember_safety "Medium" Komplexität der Schlüsselableitung für das Erinnerungs-Cookie, verwenden Sie nil, "None" (schnell), "Low", "Medium", "High" oder "Very High" (langsam).
remember_cookie_name "remember" Name des persistenten Sitzungscookies, z.B. "remember".
audience "default" Sitzungsaudience, z.B. "my-application".
subject nil Sitzungssubjekt, z.B. "[email protected]".
enforce_same_subject false Wenn auf true gesetzt, müssen Zielgruppen das gleiche Subjekt teilen. Die Bibliothek entfernt nicht übereinstimmende Zielgruppendaten beim Speichern.
stale_ttl 10 Wenn die Sitzung gespeichert wird, wird eine neue Sitzung erstellt, stale ttl gibt an, wie lange die alte noch verwendet werden kann, z.B. 10 (in Sekunden).
idling_timeout 900 Die Idling-Zeitüberschreitung gibt an, wie lange die Sitzung inaktiv sein kann, bis sie als ungültig betrachtet wird, z.B. 900 (15 Minuten) (in Sekunden), 0 deaktiviert die Überprüfungen und das Berühren.
rolling_timeout 3600 Die Rolling-Zeitüberschreitung gibt an, wie lange die Sitzung verwendet werden kann, bis sie erneuert werden muss, z.B. 3600 (eine Stunde) (in Sekunden), 0 deaktiviert die Überprüfungen und das Rolling.
absolute_timeout 86400 Die absolute Zeitüberschreitung begrenzt, wie lange die Sitzung erneuert werden kann, bis eine erneute Authentifizierung erforderlich ist, z.B. 86400 (ein Tag) (in Sekunden), 0 deaktiviert die Überprüfungen.
remember_rolling_timeout 604800 Die Erinnerungszeitüberschreitung gibt an, wie lange die persistente Sitzung als gültig betrachtet wird, z.B. 604800 (eine Woche) (in Sekunden), 0 deaktiviert die Überprüfungen und das Rolling.
remember_absolute_timeout 2592000 Die Erinnerungsabsolute Zeitüberschreitung begrenzt, wie lange die persistente Sitzung erneuert werden kann, bis eine erneute Authentifizierung erforderlich ist, z.B. 2592000 (30 Tage) (in Sekunden), 0 deaktiviert die Überprüfungen.
hash_storage_key false Ob der Speicher-Schlüssel gehasht werden soll oder nicht. Mit gehashtem Speicher-Schlüssel ist es unmöglich, Daten auf der Serverseite zu entschlüsseln, ohne auch ein Cookie zu haben, verwenden Sie nil, true oder false.
hash_subject false Ob das Subjekt gehasht werden soll oder nicht, wenn store_metadata aktiviert ist, z.B. aus PII-Gründen.
store_metadata false Ob auch Metadaten von Sitzungen gespeichert werden sollen, z.B. das Sammeln von Daten von Sitzungen für eine bestimmte Zielgruppe, die zu einem bestimmten Subjekt gehört.
touch_threshold 60 Der Berührungs-Schwellenwert steuert, wie häufig oder selten das session:refresh das Cookie berührt, z.B. 60 (eine Minute) (in Sekunden)
compression_threshold 1024 Der Kompressions-Schwellenwert steuert, wann die Daten deflationiert werden, z.B. 1024 (ein Kilobyte) (in Bytes), 0 deaktiviert die Kompression.
bind nil Bindet die Sitzung an Daten, die aus der HTTP-Anfrage oder Verbindung abgerufen wurden, verwenden Sie ip, scheme, user-agent. Z.B. { "scheme", "user-agent" } berechnet MAC unter Verwendung von HTTP-Anfrage Scheme und User-Agent-Header.
request_headers nil Menge von Headern, die an Upstream gesendet werden sollen, verwenden Sie id, audience, subject, timeout, idling-timeout, rolling-timeout, absolute-timeout. Z.B. { "id", "timeout" } setzt Session-Id und Session-Timeout-Anforderungsheader, wenn set_headers aufgerufen wird.
response_headers nil Menge von Headern, die an Downstream gesendet werden sollen, verwenden Sie id, audience, subject, timeout, idling-timeout, rolling-timeout, absolute-timeout. Z.B. { "id", "timeout" } setzt Session-Id und Session-Timeout-Antwortheader, wenn set_headers aufgerufen wird.
storage nil Der Speicher ist verantwortlich für das Speichern von Sitzungsdaten, verwenden Sie nil oder "cookie" (Daten werden im Cookie gespeichert), "dshm", "file", "memcached", "mysql", "postgres", "redis" oder "shm", oder geben Sie den Namen eines benutzerdefinierten Moduls ("custom-storage") an, oder eine Tabelle, die das Schnittstellen für die Sitzungsdaten implementiert.
dshm nil Konfiguration für dshm-Speicher, z.B. { prefix = "sessions" } (siehe unten)
file nil Konfiguration für Dateispeicher, z.B. { path = "/tmp", suffix = "session" } (siehe unten)
memcached nil Konfiguration für Memcached-Speicher, z.B. { prefix = "sessions" } (siehe unten)
mysql nil Konfiguration für MySQL / MariaDB-Speicher, z.B. { database = "sessions" } (siehe unten)
postgres nil Konfiguration für Postgres-Speicher, z.B. { database = "sessions" } (siehe unten)
redis nil Konfiguration für Redis / Redis Sentinel / Redis Cluster-Speicher, z.B. { prefix = "sessions" } (siehe unten)
shm nil Konfiguration für den Speicher in gemeinsam genutztem Speicher, z.B. { zone = "sessions" }
["custom-storage"] nil Konfiguration für benutzerdefinierten Speicher (geladen mit require "custom-storage").

Beim Speichern von Daten im Cookie ist keine zusätzliche Konfiguration erforderlich, setzen Sie einfach den storage auf nil oder "cookie".

DSHM-Speicherkonfiguration

Mit DSHM-Speicher können Sie die folgenden Einstellungen verwenden (setzen Sie den storage auf "dshm"):

Option Standard Beschreibung
prefix nil Das Präfix für die Schlüssel, die in DSHM gespeichert sind.
suffix nil Das Suffix für die Schlüssel, die in DSHM gespeichert sind.
host "127.0.0.1" Der Host, zu dem eine Verbindung hergestellt werden soll.
port 4321 Der Port, zu dem eine Verbindung hergestellt werden soll.
connect_timeout nil Steuert den Standard-Zeitüberschreitungswert, der in der connect-Methode des TCP/unix-domain-Socket-Objekts verwendet wird.
send_timeout nil Steuert den Standard-Zeitüberschreitungswert, der in der send-Methode des TCP/unix-domain-Socket-Objekts verwendet wird.
read_timeout nil Steuert den Standard-Zeitüberschreitungswert, der in der receive-Methode des TCP/unix-domain-Socket-Objekts verwendet wird.
keepalive_timeout nil Steuert die maximale Leerlaufzeit der Verbindungen im Verbindungspool.
pool nil Ein benutzerdefinierter Name für den verwendeten Verbindungspool.
pool_size nil Die Größe des Verbindungspools.
backlog nil Eine Warteschlangen-Größe, die verwendet werden soll, wenn der Verbindungspool voll ist (konfiguriert mit pool_size).
ssl nil SSL aktivieren.
ssl_verify nil Serverzertifikat überprüfen.
server_name nil Der Servername für die neue TLS-Erweiterung Server Name Indication (SNI).

Bitte beziehen Sie sich auf ngx-distributed-shm, um die erforderlichen Abhängigkeiten zu installieren.

Dateispeicherkonfiguration

Mit Dateispeicher können Sie die folgenden Einstellungen verwenden (setzen Sie den storage auf "file"):

Option Standard Beschreibung
prefix nil Dateipräfix für die Sitzung.
suffix nil Dateisuffix (oder Erweiterung ohne .) für die Sitzung.
pool nil Name des Thread-Pools, unter dem das Schreiben in die Datei erfolgt (nur auf Linux verfügbar).
path (tmp-Verzeichnis) Pfad (oder Verzeichnis), unter dem die Sitzungsdateien erstellt werden.

Die Implementierung erfordert LuaFileSystem, das Sie mit LuaRocks installieren können:

 luarocks install LuaFileSystem

Memcached-Speicherkonfiguration

Mit Memcached können Sie die folgenden Einstellungen verwenden (setzen Sie den storage auf "memcached"):

Option Standard Beschreibung
prefix nil Präfix für die in Memcached gespeicherten Schlüssel.
suffix nil Suffix für die in Memcached gespeicherten Schlüssel.
host 127.0.0.1 Der Host, zu dem eine Verbindung hergestellt werden soll.
port 11211 Der Port, zu dem eine Verbindung hergestellt werden soll.
socket nil Die Socket-Datei, zu der eine Verbindung hergestellt werden soll.
connect_timeout nil Steuert den Standard-Zeitüberschreitungswert, der in der connect-Methode des TCP/unix-domain-Socket-Objekts verwendet wird.
send_timeout nil Steuert den Standard-Zeitüberschreitungswert, der in der send-Methode des TCP/unix-domain-Socket-Objekts verwendet wird.
read_timeout nil Steuert den Standard-Zeitüberschreitungswert, der in der receive-Methode des TCP/unix-domain-Socket-Objekts verwendet wird.
keepalive_timeout nil Steuert die maximale Leerlaufzeit der Verbindungen im Verbindungspool.
pool nil Ein benutzerdefinierter Name für den verwendeten Verbindungspool.
pool_size nil Die Größe des Verbindungspools.
backlog nil Eine Warteschlangen-Größe, die verwendet werden soll, wenn der Verbindungspool voll ist (konfiguriert mit pool_size).
ssl false SSL aktivieren
ssl_verify nil Serverzertifikat überprüfen
server_name nil Der Servername für die neue TLS-Erweiterung Server Name Indication (SNI).

MySQL / MariaDB-Speicherkonfiguration

Mit MySQL / MariaDB können Sie die folgenden Einstellungen verwenden (setzen Sie den storage auf "mysql"):

Option Standard Beschreibung
host "127.0.0.1" Der Host, zu dem eine Verbindung hergestellt werden soll.
port 3306 Der Port, zu dem eine Verbindung hergestellt werden soll.
socket nil Die Socket-Datei, zu der eine Verbindung hergestellt werden soll.
username nil Der Datenbankbenutzername zur Authentifizierung.
password nil Passwort zur Authentifizierung, kann je nach Serverkonfiguration erforderlich sein.
charset "ascii" Der Zeichensatz, der bei der MySQL-Verbindung verwendet wird.
database nil Der Datenbankname, zu dem eine Verbindung hergestellt werden soll.
table_name "sessions" Name der Datenbanktabelle, in der die Sitzungsdaten gespeichert werden sollen.
table_name_meta "sessions_meta" Name der Datenbank-Metadaten-Tabelle, in der die Sitzungsmetadaten gespeichert werden sollen.
max_packet_size 1048576 Die obere Grenze für die Antwortpakete, die vom MySQL-Server gesendet werden (in Bytes).
connect_timeout nil Steuert den Standard-Zeitüberschreitungswert, der in der connect-Methode des TCP/unix-domain-Socket-Objekts verwendet wird.
send_timeout nil Steuert den Standard-Zeitüberschreitungswert, der in der send-Methode des TCP/unix-domain-Socket-Objekts verwendet wird.
read_timeout nil Steuert den Standard-Zeitüberschreitungswert, der in der receive-Methode des TCP/unix-domain-Socket-Objekts verwendet wird.
keepalive_timeout nil Steuert die maximale Leerlaufzeit der Verbindungen im Verbindungspool.
pool nil Ein benutzerdefinierter Name für den verwendeten Verbindungspool.
pool_size nil Die Größe des Verbindungspools.
backlog nil Eine Warteschlangen-Größe, die verwendet werden soll, wenn der Verbindungspool voll ist (konfiguriert mit pool_size).
ssl false SSL aktivieren.
ssl_verify nil Serverzertifikat überprüfen.

Sie müssen auch die folgenden Tabellen in Ihrer Datenbank erstellen:

--
-- Datenbanktabelle, die Sitzungsdaten speichert.
--
CREATE TABLE IF NOT EXISTS sessions (
  sid  CHAR(43) PRIMARY KEY,
  name VARCHAR(255),
  data MEDIUMTEXT,
  exp  DATETIME,
  INDEX (exp)
) CHARACTER SET ascii;

--
-- Sitzungs-Metadatentabelle.
--
-- Dies ist nur erforderlich, wenn Sie Sitzungsmetadaten speichern möchten.
--
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;

Postgres-Konfiguration

Mit Postgres können Sie die folgenden Einstellungen verwenden (setzen Sie den storage auf "postgres"):

Option Standard Beschreibung
host "127.0.0.1" Der Host, zu dem eine Verbindung hergestellt werden soll.
port 5432 Der Port, zu dem eine Verbindung hergestellt werden soll.
application 5432 Setzen Sie den Namen der Verbindung, wie in pg_stat_activity angezeigt (standardmäßig "pgmoon").
username "postgres" Der Datenbankbenutzername zur Authentifizierung.
password nil Passwort zur Authentifizierung, kann je nach Serverkonfiguration erforderlich sein.
database nil Der Datenbankname, zu dem eine Verbindung hergestellt werden soll.
table_name "sessions" Name der Datenbanktabelle, in der die Sitzungsdaten gespeichert werden sollen (kann mit database schema vorangestellt werden).
table_name_meta "sessions_meta" Name der Datenbank-Metadaten-Tabelle, in der die Sitzungsmetadaten gespeichert werden sollen (kann mit database schema vorangestellt werden).
connect_timeout nil Steuert den Standard-Zeitüberschreitungswert, der in der connect-Methode des TCP/unix-domain-Socket-Objekts verwendet wird.
send_timeout nil Steuert den Standard-Zeitüberschreitungswert, der in der send-Methode des TCP/unix-domain-Socket-Objekts verwendet wird.
read_timeout nil Steuert den Standard-Zeitüberschreitungswert, der in der receive-Methode des TCP/unix-domain-Socket-Objekts verwendet wird.
keepalive_timeout nil Steuert die maximale Leerlaufzeit der Verbindungen im Verbindungspool.
pool nil Ein benutzerdefinierter Name für den verwendeten Verbindungspool.
pool_size nil Die Größe des Verbindungspools.
backlog nil Eine Warteschlangen-Größe, die verwendet werden soll, wenn der Verbindungspool voll ist (konfiguriert mit pool_size).
ssl false SSL aktivieren.
ssl_verify nil Serverzertifikat überprüfen.
ssl_required nil Brechen Sie die Verbindung ab, wenn der Server keine SSL-Verbindungen unterstützt.

Sie müssen auch die folgenden Tabellen in Ihrer Datenbank erstellen:

--
-- Datenbanktabelle, die Sitzungsdaten speichert.
--
CREATE TABLE IF NOT EXISTS sessions (
  sid  TEXT PRIMARY KEY,
  name TEXT,
  data TEXT,
  exp  TIMESTAMP WITH TIME ZONE
);
CREATE INDEX ON sessions (exp);

--
-- Sitzungs-Metadatentabelle.
--
-- Dies ist nur erforderlich, wenn Sie Sitzungsmetadaten speichern möchten.
--
CREATE TABLE IF NOT EXISTS sessions_meta (
  aud TEXT,
  sub TEXT,
  sid TEXT REFERENCES sessions (sid) ON DELETE CASCADE ON UPDATE CASCADE,
  PRIMARY KEY (aud, sub, sid)
);

Die Implementierung erfordert pgmoon, das Sie mit LuaRocks installieren können:

 luarocks install pgmoon

Redis-Konfiguration

Die Sitzungsbibliothek unterstützt Einzel-Redis-, Redis-Sentinel- und Redis-Clusterverbindungen. Gemeinsame Konfigurationseinstellungen unter ihnen:

Option Standard Beschreibung
prefix nil Präfix für die in Redis gespeicherten Schlüssel.
suffix nil Suffix für die in Redis gespeicherten Schlüssel.
username nil Der Datenbankbenutzername zur Authentifizierung.
password nil Passwort zur Authentifizierung.
connect_timeout nil Steuert den Standard-Zeitüberschreitungswert, der in der connect-Methode des TCP/unix-domain-Socket-Objekts verwendet wird.
send_timeout nil Steuert den Standard-Zeitüberschreitungswert, der in der send-Methode des TCP/unix-domain-Socket-Objekts verwendet wird.
read_timeout nil Steuert den Standard-Zeitüberschreitungswert, der in der receive-Methode des TCP/unix-domain-Socket-Objekts verwendet wird.
keepalive_timeout nil Steuert die maximale Leerlaufzeit der Verbindungen im Verbindungspool.
pool nil Ein benutzerdefinierter Name für den verwendeten Verbindungspool.
pool_size nil Die Größe des Verbindungspools.
backlog nil Eine Warteschlangen-Größe, die verwendet werden soll, wenn der Verbindungspool voll ist (konfiguriert mit pool_size).
ssl false SSL aktivieren
ssl_verify nil Serverzertifikat überprüfen
server_name nil Der Servername für die neue TLS-Erweiterung Server Name Indication (SNI).

Die einzelne Redis-Implementierung wird ausgewählt, wenn Sie weder sentinels noch nodes übergeben, was zur Auswahl der sentinel- oder cluster-Implementierung führen würde.

Einzel-Redis-Konfiguration

Einzel-Redis hat die folgenden zusätzlichen Konfigurationsoptionen (setzen Sie den storage auf "redis"):

Option Standard Beschreibung
host "127.0.0.1" Der Host, zu dem eine Verbindung hergestellt werden soll.
port 6379 Der Port, zu dem eine Verbindung hergestellt werden soll.
socket nil Die Socket-Datei, zu der eine Verbindung hergestellt werden soll.
database nil Die Datenbank, zu der eine Verbindung hergestellt werden soll.

Redis-Sentinels-Konfiguration

Redis Sentinel hat die folgenden zusätzlichen Konfigurationsoptionen (setzen Sie den storage auf "redis" und konfigurieren Sie die sentinels):

Option Standard Beschreibung
master nil Name des Masters.
role nil "master" oder "slave".
socket nil Die Socket-Datei, zu der eine Verbindung hergestellt werden soll.
sentinels nil Redis-Sentinels.
sentinel_username nil Optionaler Sentinel-Benutzername.
sentinel_password nil Optionales Sentinel-Passwort.
database nil Die Datenbank, zu der eine Verbindung hergestellt werden soll.

Die sentinels ist ein Array von Sentinel-Datensätzen:

Option Standard Beschreibung
host nil Der Host, zu dem eine Verbindung hergestellt werden soll.
port nil Der Port, zu dem eine Verbindung hergestellt werden soll.

Die sentinel-Implementierung wird ausgewählt, wenn Sie sentinels als Teil der redis-Konfiguration übergeben (und keine nodes übergeben, was die cluster-Implementierung auswählen würde).

Die Implementierung erfordert lua-resty-redis-connector, das Sie mit LuaRocks installieren können:

 luarocks install lua-resty-redis-connector

Redis-Cluster-Konfiguration

Redis Cluster hat die folgenden zusätzlichen Konfigurationsoptionen (setzen Sie den storage auf "redis" und konfigurieren Sie die nodes):

Option Standard Beschreibung
name nil Redis-Clustername.
nodes nil Redis-Clusterknoten.
lock_zone nil Gemeinsamer Dictionary-Name für Sperren.
lock_prefix nil Gemeinsamer Dictionary-Name-Präfix für Sperren.
max_redirections nil Maximale Anzahl der Wiederholversuche für Umleitungen.
max_connection_attempts nil Maximale Anzahl der Wiederholversuche für Verbindungen.
max_connection_timeout nil Maximale Verbindungszeitüberschreitung insgesamt unter den Wiederholungen.

Die nodes ist ein Array von Clusterknoten-Datensätzen:

Option Standard Beschreibung
ip "127.0.0.1" Die IP-Adresse, zu der eine Verbindung hergestellt werden soll.
port 6379 Der Port, zu dem eine Verbindung hergestellt werden soll.

Die cluster-Implementierung wird ausgewählt, wenn Sie nodes als Teil der redis-Konfiguration übergeben.

Damit cluster ordnungsgemäß funktioniert, müssen Sie lock_zone konfigurieren, fügen Sie dies also auch zu Ihrer Nginx-Konfiguration hinzu:

lua_shared_dict redis_cluster_locks 100k;

Und setzen Sie die lock_zone auf "redis_cluster_locks".

Die Implementierung erfordert resty-redis-cluster oder kong-redis-cluster, die Sie mit LuaRocks installieren können:

 luarocks install resty-redis-cluster
## oder luarocks install kong-redis-cluster

SHM-Konfiguration

Mit SHM-Speicher können Sie die folgenden Einstellungen verwenden (setzen Sie den storage auf "shm"):

Option Standard Beschreibung
prefix nil Präfix für die in SHM gespeicherten Schlüssel.
suffix nil Suffix für die in SHM gespeicherten Schlüssel.
zone "sessions" Ein Name des gemeinsam genutzten Speicherbereichs.

Sie müssen auch ein gemeinsames Dictionary zone in Nginx erstellen:

lua_shared_dict sessions 10m;

Hinweis: Möglicherweise müssen Sie die Größe des gemeinsam genutzten Speicherbereichs entsprechend Ihren Anforderungen anpassen.

API

LDoc-generierte API-Dokumente können auch unter bungle.github.io/lua-resty-session angesehen werden.

Initialisierung

session.init

Syntax: session.init(configuration)

Initialisiert die Sitzungsbibliothek.

Diese Funktion kann in den Phasen init oder init_worker in OpenResty aufgerufen werden, um die globalen Standardkonfigurationen für alle Sitzungsinstanzen, die von dieser Bibliothek erstellt werden, festzulegen.

require "resty.session".init({
  audience = "my-application",
  storage = "redis",
  redis = {
    username = "session",
    password = "storage",
  },
})

Siehe Konfiguration für mögliche Konfigurationseinstellungen.

Konstruktoren

session.new

Syntax: session = session.new(configuration)

Erstellt eine neue Sitzungsinstanz.

local session = require "resty.session".new()
-- ODER
local session = require "resty.session".new({
  audience = "my-application",
})

Siehe Konfiguration für mögliche Konfigurationseinstellungen.

Hilfsfunktionen

session.open

Syntax: session, err, exists = session.open(configuration)

Dies kann verwendet werden, um eine Sitzung zu öffnen, und es wird entweder eine vorhandene Sitzung oder eine neue Sitzung zurückgegeben. Der Rückgabewert exists (ein Boolean) gibt an, ob es sich um eine vorhandene oder neue Sitzung handelt. Der Rückgabewert err (ein String) enthält eine Nachricht, warum das Öffnen möglicherweise fehlgeschlagen ist (die Funktion gibt auch session zurück).

local session = require "resty.session".open()
-- ODER
local session, err, exists = require "resty.session".open({
  audience = "my-application",
})

Siehe Konfiguration für mögliche Konfigurationseinstellungen.

session.start

Syntax: session, err, exists, refreshed = session.start(configuration)

Dies kann verwendet werden, um eine Sitzung zu starten, und es wird entweder eine vorhandene Sitzung oder eine neue Sitzung zurückgegeben. Falls eine vorhandene Sitzung vorhanden ist, wird die Sitzung ebenfalls aktualisiert (falls erforderlich). Der Rückgabewert exists (ein Boolean) gibt an, ob es sich um eine vorhandene oder neue Sitzung handelt. Der Rückgabewert refreshed (ein Boolean) gibt an, ob der Aufruf von refresh erfolgreich war. Der Rückgabewert err (ein String) enthält eine Nachricht, warum das Öffnen oder Aktualisieren möglicherweise fehlgeschlagen ist (die Funktion gibt auch session zurück).

local session = require "resty.session".start()
-- ODER
local session, err, exists, refreshed = require "resty.session".start({
  audience = "my-application",
})

Siehe Konfiguration für mögliche Konfigurationseinstellungen.

session.logout

Syntax: ok, err, exists, logged_out = session.logout(configuration)

Meldet sich von einer bestimmten Zielgruppe ab.

Ein einzelnes Sitzungscookie kann zwischen mehreren Zielgruppen (oder Anwendungen) geteilt werden, daher besteht die Notwendigkeit, sich nur von einer einzigen Zielgruppe abmelden zu können, während die Sitzung für die anderen Zielgruppen beibehalten wird. Der Rückgabewert exists (ein Boolean) gibt an, ob die Sitzung vorhanden war. Der Rückgabewert logged_out (ein Boolean) signalisiert, ob die Sitzung vorhanden war und auch abgemeldet wurde. Der Rückgabewert err (ein String) enthält einen Grund, warum die Sitzung nicht vorhanden war oder warum die Abmeldung fehlgeschlagen ist. Der Rückgabewert ok (truthy) ist true, wenn die Sitzung vorhanden war und erfolgreich abgemeldet wurde.

Wenn es nur eine einzige Zielgruppe gibt, kann dies als gleichwertig zu session.destroy betrachtet werden.

Wenn die letzte Zielgruppe abgemeldet wird, wird das Cookie ebenfalls zerstört und auf dem Client ungültig gemacht.

require "resty.session".logout()
-- ODER
local ok, err, exists, logged_out = require "resty.session".logout({
  audience = "my-application",
})

Siehe Konfiguration für mögliche Konfigurationseinstellungen.

session.destroy

Syntax: ok, err, exists, destroyed = session.destroy(configuration)

Zerstört die gesamte Sitzung und löscht die Cookies.

Ein einzelnes Sitzungscookie kann zwischen mehreren Zielgruppen (oder Anwendungen) geteilt werden, daher besteht die Notwendigkeit, sich nur von einer einzigen Zielgruppe abmelden zu können, während die Sitzung für die anderen Zielgruppen beibehalten wird. Der Rückgabewert exists (ein Boolean) gibt an, ob die Sitzung vorhanden war. Der Rückgabewert destroyed (ein Boolean) signalisiert, ob die Sitzung vorhanden war und ebenfalls zerstört wurde. Der Rückgabewert err (ein String) enthält einen Grund, warum die Sitzung nicht vorhanden war oder warum die Abmeldung fehlgeschlagen ist. Der Rückgabewert ok (truthy) ist true, wenn die Sitzung vorhanden war und erfolgreich abgemeldet wurde.

require "resty.session".destroy()
-- ODER
local ok, err, exists, destroyed = require "resty.session".destroy({
  cookie_name = "auth",
})

Siehe Konfiguration für mögliche Konfigurationseinstellungen.

Instanzmethoden

session:open

Syntax: ok, err = session:open()

Dies kann verwendet werden, um eine Sitzung zu öffnen. Es gibt true zurück, wenn die Sitzung geöffnet und validiert wurde. Andernfalls gibt es nil und eine Fehlermeldung zurück.

local session = require "resty.session".new()
local ok, err = session:open()
if ok then
  -- Sitzung existiert

else
  -- Sitzung existierte nicht oder war ungültig
end

session:save

Syntax: ok, err = session:save()

Speichert die Sitzungsdaten und gibt ein neues Sitzungscookie mit einer neuen Sitzungs-ID aus. Wenn remember aktiviert ist, wird auch ein neues persistentes Cookie ausgegeben und möglicherweise die Daten im Backend-Speicher gespeichert. Es gibt true zurück, wenn die Sitzung gespeichert wurde. Andernfalls gibt es nil und eine Fehlermeldung zurück.

local session = require "resty.session".new()
session:set_subject("john")
local ok, err = session:save()
if not ok then
  -- Fehler beim Speichern der Sitzung
end

session:touch

Syntax: ok, err = session:touch()

Aktualisiert den Leerlaufoffset der Sitzung, indem ein aktualisiertes Sitzungscookie gesendet wird. Es sendet nur das Client-Cookie und ruft niemals Backend-Sitzungsspeicher-APIs auf. Normalerweise wird session:refresh verwendet, um dies indirekt aufzurufen. Im Fehlerfall gibt es nil und eine Fehlermeldung zurück, andernfalls true.

local session, err, exists = require "resty.session".open()
if exists then
  ok, err = session:touch()
end

session:refresh

Syntax: ok, err = session:refresh()

Speichert entweder die Sitzung (erstellt eine neue Sitzungs-ID) oder berührt die Sitzung, abhängig davon, ob die Rolling-Zeitüberschreitung näher rückt, was standardmäßig bedeutet, dass 3/4 der Rolling-Zeitüberschreitung aufgebraucht sind, also 45 Minuten bei der standardmäßigen Rolling-Zeitüberschreitung von einer Stunde. Die Berührung hat einen Schwellenwert, standardmäßig eine Minute, sodass sie in einigen Fällen übersprungen werden kann (Sie können session:touch() aufrufen, um dies zu erzwingen). Im Fehlerfall gibt es nil und eine Fehlermeldung zurück, andernfalls true.

local session, err, exists = require "resty.session".open()
if exists then
  local ok, err = session:refresh()
end

Der obige Code sieht ein wenig aus wie der session.start()-Hilfsfunktion.

session:logout

Syntax: ok, err = session:logout()

Die Abmeldung zerstört entweder die Sitzung oder löscht einfach die Daten für die aktuelle Zielgruppe und speichert sie (Abmeldung von der aktuellen Zielgruppe). Im Fehlerfall gibt es nil und eine Fehlermeldung zurück, andernfalls true.

local session, err, exists = require "resty.session".open()
if exists then
  local ok, err = session:logout()
end

session:destroy

Syntax: ok, err = session:destroy()

Zerstört die Sitzung und löscht die Cookies. Im Fehlerfall gibt es nil und eine Fehlermeldung zurück, andernfalls true.

local session, err, exists = require "resty.session".open()
if exists then
  local ok, err = session:destroy()
end

session:close

Syntax: session:close()

Schließt einfach die Sitzungsinstanz, sodass sie nicht mehr verwendet werden kann.

local session = require "resty.session".new()
session:set_subject("john")
local ok, err = session:save()
if not ok then
  -- Fehler beim Speichern der Sitzung
end
session:close()

session:set_data

Syntax: session:set_data(data)

Setzt Sitzungsdaten. Die data muss eine Tabelle sein.

local session, err, exists = require "resty.session".open()
if not exists then
   session:set_data({
     cart = {},
   })
  session:save()
end

session:get_data

Syntax: data = session:get_data()

Holt Sitzungsdaten.

local session, err, exists = require "resty.session".open()
if exists then
  local data = session:get_data()
  ngx.req.set_header("Authorization", "Bearer " .. data.access_token)
end

session:set

Syntax: session:set(key, value)

Setzt einen Wert in der Sitzung.

local session, err, exists = require "resty.session".open()
if not exists then
  session:set("access-token", "eyJ...")
  session:save()
end

session:get

Syntax: value = session:get(key)

Holt einen Wert aus der Sitzung.

local session, err, exists = require "resty.session".open()
if exists then
  local access_token = session:get("access-token")
  ngx.req.set_header("Authorization", "Bearer " .. access_token)
end

session:set_audience

Syntax: session:set_audience(audience)

Setzt die Sitzungsaudience.

local session = require "resty.session".new()
session.set_audience("my-service")

session:get_audience

Syntax: audience = session:get_audience()

Setzt das Sitzungssubjekt.

session:set_subject

Syntax: session:set_subject(subject)

Setzt das Sitzungssubjekt.

local session = require "resty.session".new()
session.set_subject("[email protected]")

session:get_subject

Syntax: subject = session:get_subject()

Holt das Sitzungssubjekt.

local session, err, exists = require "resty.session".open()
if exists then
  local subject = session.get_subject()
end

session:get_property

Syntax: value = session:get_property(name)

Holt eine Sitzungseigenschaft. Mögliche Eigenschaftsnamen:

  • "id": 43 Bytes Sitzungs-ID (gleich wie nonce, aber base64-url-kodiert)
  • "nonce": 32 Bytes nonce (gleich wie Sitzungs-ID, aber in Rohdaten)
  • "audience": Aktuelle Sitzungsaudience
  • "subject": Aktuelles Sitzungssubjekt
  • "timeout": Nächste Zeitüberschreitung (in Sekunden) (was davon übrig bleibt)
  • "idling-timeout": Sitzung-Leerlaufzeitüberschreitung (in Sekunden) (was davon übrig bleibt)
  • "rolling-timeout": Sitzung-Rolling-Zeitüberschreitung (in Sekunden) (was davon übrig bleibt)
  • "absolute-timeout": Sitzung-absolute Zeitüberschreitung (in Sekunden) (was davon übrig bleibt)

Hinweis: Der zurückgegebene Wert kann nil sein.

local session, err, exists = require "resty.session".open()
if exists then
  local timeout = session.get_property("timeout")
end

session:set_remember

Syntax: session:set_remember(value)

Setzt persistente Sitzungen ein/aus.

In vielen Anmeldeformularen wird dem Benutzer die Option "Angemeldet bleiben" angeboten. Sie können diese Funktion basierend auf der Auswahl des Benutzers aufrufen.

local session = require "resty.session".new()
if ngx.var.args.remember then
  session:set_remember(true)
end
session:set_subject(ngx.var.args.username)
session:save()

session:get_remember

Syntax: remember = session:get_remember()

Holt den Status der persistenten Sitzungen.

local session, err, exists = require "resty.session".open()
if exists then
  local remember = session.get_remember()
end

Syntax: ok, err = session:clear_request_cookie()

Ändert die Anforderungsheader, indem die sitzungsbezogenen Cookies entfernt werden. Dies ist nützlich, wenn Sie die Sitzungsbibliothek auf einem Proxy-Server verwenden und nicht möchten, dass die Sitzungscookies an den Upstream-Dienst weitergeleitet werden. Im Fehlerfall gibt es nil und eine Fehlermeldung zurück, andernfalls true (was ignoriert werden kann).

local session, err, exists = require "resty.session".open()
if exists then
  session:clear_request_cookie()
end

session:set_headers

Syntax: ok, err = session:set_headers(arg1, arg2, ...)

Setzt Anforderungs- und Antwortheader basierend auf der Konfiguration. Im Fehlerfall gibt es nil und eine Fehlermeldung zurück, andernfalls true (was ignoriert werden kann).

local session, err, exists = require "resty.session".open({
  request_headers = { "audience", "subject", "id" },
  response_headers = { "timeout", "idling-timeout", "rolling-timeout", "absolute-timeout" },
})
if exists then
  session:set_headers()
end

Wenn ohne Argumente aufgerufen, werden die Anforderungsheader gesetzt, die mit request_headers konfiguriert sind, und die Antwortheader, die mit response_headers konfiguriert sind.

Siehe Konfiguration für mögliche Headernamen.

session:set_request_headers

Syntax: ok, err = session:set_request_headers(arg1, arg2, ...)

Setzt Anforderungsheader. Im Fehlerfall gibt es nil und eine Fehlermeldung zurück, andernfalls true (was ignoriert werden kann).

local session, err, exists = require "resty.session".open()
if exists then
  session:set_request_headers("audience", "subject", "id")
end

Wenn ohne Argumente aufgerufen, werden die Anforderungsheader gesetzt, die mit request_headers konfiguriert sind.

Siehe Konfiguration für mögliche Headernamen.

session:set_response_headers

Syntax: ok, err = session:set_response_headers(arg1, arg2, ...)

Setzt Antwortheader. Im Fehlerfall gibt es nil und eine Fehlermeldung zurück, andernfalls true (was ignoriert werden kann).

local session, err, exists = require "resty.session".open()
if exists then
  session:set_response_headers("timeout", "idling-timeout", "rolling-timeout", "absolute-timeout")
end

Wenn ohne Argumente aufgerufen, werden die Antwortheader gesetzt, die mit response_headers konfiguriert sind.

Siehe Konfiguration für mögliche Headernamen.

session.info:set

Syntax: session.info:set(key, value)

Setzt einen Wert im Sitzungsinformationsspeicher. Der Sitzungsinformationsspeicher kann in Szenarien verwendet werden, in denen Sie Daten im serverseitigen Speicher speichern möchten, aber keine neue Sitzung erstellen und ein neues Sitzungscookie senden möchten. Die Daten des Informationsspeichers werden nicht berücksichtigt, wenn der Authentifizierungstag oder der Nachrichten-Authentifizierungscode überprüft wird. Wenn Sie dies für Daten verwenden möchten, die verschlüsselt werden müssen, müssen Sie den Wert vor dem Übergeben an diese Funktion verschlüsseln.

local session, err, exists = require "resty.session".open()
if exists then
  session.info:set("last-access", ngx.now())
  session.info:save()
end

Mit Cookie-Speicher funktioniert dies immer noch, ist aber dann fast dasselbe wie session:set.

session.info:get

Syntax: value = session.info:get(key)

Holt einen Wert aus dem Sitzungsinformationsspeicher.

local session, err, exists = require "resty.session".open()
if exists then
  local last_access = session.info:get("last-access")
end

session.info:save

Syntax: ok, err = session.info:save()

Speichert Informationen. Aktualisiert nur den Backend-Speicher. Sendet kein neues Cookie (außer bei Cookie-Speicher).

local session = require "resty.session".new()
session.info:set("last-access", ngx.now())
local ok, err = session.info:save()
[ HEADER -------------------------------------------------------------------------------------]
[ Typ || Flags || SID || Erstellungszeit || Rolling Offset || Größe || Tag || Idling Offset || Mac ]
[ 1B   || 2B    || 32B || 5B         || 4B             || 3B   || 16B || 3B            || 16B ]

und

[ PAYLOAD --]
[ Daten  *B  ]

Sowohl der HEADER als auch der PAYLOAD sind base64-url-kodiert, bevor sie in einem Set-Cookie-Header platziert werden. Bei Verwendung eines serverseitigen Speichers wird der PAYLOAD nicht im Cookie platziert. Bei Cookie-Speicher wird der base64-url-kodierte Header mit dem base64-url-kodierten Payload verknüpft.

Der HEADER hat eine feste Größe von 82 Bytes binär oder 110 Bytes in base64-url-kodierter Form.

Headerfelder erklärt:

  • Typ: Nummer 1 binär in einem einzelnen Little-Endian-Byte gepackt (derzeit der einzige unterstützte Typ).
  • Flags: binär gepackte Flags (kurz) in einer zwei Byte Little-Endian-Form.
  • SID: 32 Bytes kryptografisch zufällige Daten (Sitzungs-ID).
  • Erstellungszeit: binär gepackte Sekunden seit der Epoche in einer Little-Endian-Form, auf 5 Bytes gekürzt.
  • Rolling Offset: binär gepackte Sekunden seit der Erstellungszeit in einer Little-Endian-Form (ganzzahlig).
  • Größe: binär gepackte Datengröße in einer drei Byte Little-Endian-Form.
  • Tag: 16 Bytes Authentifizierungstag aus der AES-256-GCM-Verschlüsselung der Daten.
  • Idling Offset: binär gepackte Sekunden seit der Erstellungszeit + Rolling Offset in einer Little-Endian-Form, auf 3 Bytes gekürzt.
  • Mac: 16 Bytes Nachrichten-Authentifizierungscode des Headers.

Datenverschlüsselung

  1. Initiales Schlüsselmaterial (IKM):
  2. IKM aus secret ableiten, indem secret mit SHA-256 gehasht wird, oder
  3. Verwenden Sie 32 Byte IKM, wenn an die Bibliothek mit ikm übergeben.
  4. Generieren Sie 32 Bytes kryptografisch zufällige Sitzungs-ID (sid).
  5. Leiten Sie 32 Byte Verschlüsselungsschlüssel und 12 Byte Initialisierungsvektor mit HKDF unter Verwendung von SHA-256 ab (im FIPS-Modus wird stattdessen PBKDF2 mit SHA-256 verwendet).
  6. Verwenden Sie HKDF extract, um einen neuen Schlüssel aus ikm abzuleiten, um key zu erhalten (dieser Schritt kann nur einmal pro ikm durchgeführt werden):
    • Ausgabelänge: 32
    • Digest: "sha256"
    • Schlüssel: <ikm>
    • Modus: nur extrahieren
    • Info: ""
    • Salz: ""
  7. Verwenden Sie HKDF expand, um 44 Bytes output abzuleiten:
    • Ausgabelänge: 44
    • Digest: "sha256"
    • Schlüssel: <key>
    • Modus: nur erweitern
    • Info: "encryption:<sid>"
    • Salz: ""
  8. Die ersten 32 Bytes von output sind der Verschlüsselungsschlüssel (aes-key), und die letzten 12 Bytes sind der Initialisierungsvektor (iv).
  9. Verschlüsseln Sie plaintext (JSON-kodiert und optional deflationiert) mit AES-256-GCM, um ciphertext und tag zu erhalten.
  10. Cipher: "aes-256-gcm"
  11. Schlüssel: <aes-key>
  12. iv: <iv>
  13. plaintext: <plaintext>
  14. aad: Verwenden Sie die ersten 47 Bytes des header als aad, die Folgendes umfasst:
    1. Typ
    2. Flags
    3. Sitzungs-ID
    4. Erstellungszeit
    5. Rolling Offset
    6. Datengröße

Es gibt eine Variation für remember-Cookies in Schritt 3, bei der wir möglicherweise PBKDF2 anstelle von HKDF verwenden, abhängig von der Einstellung remember_safety (wir verwenden es auch im FIPS-Modus). Die PBKDF2-Einstellungen:

  • Ausgabelänge: 44
  • Digest: "sha256"
  • Passwort: <key>
  • Salz: "encryption:<sid>"
  • Iterationen: <1000|10000|100000|1000000>
  • pkcs5: 1 (FIPS-konform in unserem Anwendungsfall, aber erforderlich, um die SP800-132-basierten Überprüfungen zu deaktivieren, wie z.B. die Anzahl der Iterationen, siehe: https://docs.openssl.org/master/man7/provider-kdf/#kdf-parameters)

Die Iterationszahlen basieren auf der Einstellung remember_safety ("Low", "Medium", "High", "Very High"), wenn remember_safety auf "None" gesetzt ist, verwenden wir das HDKF wie oben.

Hinweis: Aus Gründen der Abwärtskompatibilität haben wir die SP800-132-Konformitätsprüfungen im FIPS-Modus deaktiviert. Diese Überprüfungen stellen sicher, dass die Salzlänge mindestens 128 Bits beträgt, die abgeleitete Schlüssellänge mindestens 112 Bits beträgt und die Anzahl der Iterationen mindestens 1000 beträgt. Diese Überprüfungen sind standardmäßig im Standardanbieter von OpenSSL deaktiviert, aber standardmäßig im FIPS-Anbieter aktiviert.

  1. Leiten Sie 32 Byte Authentifizierungsschlüssel (mac_key) mit HKDF unter Verwendung von SHA-256 ab (im FIPS-Modus wird stattdessen PBKDF2 mit SHA-256 verwendet):
    1. Verwenden Sie HKDF extract, um einen neuen Schlüssel aus ikm abzuleiten, um key zu erhalten (dieser Schritt kann nur einmal pro ikm durchgeführt werden und wiederverwendet werden, wenn der Verschlüsselungsschlüssel generiert wird):
      • Ausgabelänge: 32
      • Digest: "sha256"
      • Schlüssel: <ikm>
      • Modus: nur extrahieren
      • Info: ""
      • Salz: ""
    2. Verwenden Sie HKDF expand, um 32 Bytes mac-key abzuleiten:
      • Ausgabelänge: 32
      • Digest: "sha256"
      • Schlüssel: <key>
      • Modus: nur erweitern
      • Info: "authentication:<sid>"
      • Salz: ""
  2. Berechnen Sie den Nachrichten-Authentifizierungscode mit HMAC-SHA256:
  3. Digest: "sha256"
  4. Schlüssel: <mac-key>
  5. Nachricht: Verwenden Sie die ersten 66 Bytes des header, die Folgendes umfasst:
    1. Typ
    2. Flags
    3. Sitzungs-ID
    4. Erstellungszeit
    5. Rolling Offset
    6. Datengröße
    7. Tag
    8. Idling Offset

Benutzerdefiniertes Speicherinterface

Wenn Sie benutzerdefinierten Speicher implementieren möchten, müssen Sie das folgende Interface implementieren:

---
-- <custom> Backend für die Sitzungsbibliothek
--
-- @module <custom>


---
-- Speicher
-- @section instance


local metatable = {}


metatable.__index = metatable


function metatable.__newindex()
  error("Versuch, eine schreibgeschützte Tabelle zu aktualisieren", 2)
end


---
-- Speichert Sitzungsdaten.
--
-- @function instance:set
-- @tparam string name Cookie-Name
-- @tparam string key Sitzungs-Schlüssel
-- @tparam string value Sitzungs-Wert
-- @tparam number ttl Sitzungs-TTL
-- @tparam number current_time Aktuelle Zeit
-- @tparam[opt] string old_key Alte Sitzungs-ID
-- @tparam string stale_ttl Stale TTL
-- @tparam[opt] table metadata Tabelle von Metadaten
-- @treturn true|nil ok
-- @treturn string Fehlermeldung
function metatable:set(name, key, value, ttl, current_time, old_key, stale_ttl, metadata)
  -- NYI
end


---
-- Ruft Sitzungsdaten ab.
--
-- @function instance:get
-- @tparam string name Cookie-Name
-- @tparam string key Sitzungs-Schlüssel
-- @treturn string|nil Sitzungsdaten
-- @treturn string Fehlermeldung
function metatable:get(name, key)
  -- NYI
end


---
-- Löscht Sitzungsdaten.
--
-- @function instance:delete
-- @tparam string name Cookie-Name
-- @tparam string key Sitzungs-Schlüssel
-- @tparam[opt] table metadata Sitzungsmetadaten
-- @treturn boolean|nil Sitzungsdaten
-- @treturn string Fehlermeldung
function metatable:delete(name, key, current_time, metadata)
  -- NYI
end


local storage = {}


---
-- Konstruktoren
-- @section constructors


---
-- Konfiguration
-- @section configuration


---
-- <custom> Speicher-Backend-Konfiguration
-- @field <field-name> TBD
-- @table configuration


---
-- Erstellt einen <custom> Speicher.
--
-- Dies erstellt eine neue Instanz des gemeinsam genutzten Speichers.
--
-- @function module.new
-- @tparam[opt]  table   configuration  <custom> Speicher @{configuration}
-- @treturn      table                  <custom> Speicherinstanz
function storage.new(configuration)
  -- NYI
  -- return setmetatable({}, metatable)
end


return storage

Bitte überprüfen Sie die vorhandenen Implementierungen für die Details. Und bitte machen Sie einen Pull-Request, damit wir es direkt in die Bibliothek integrieren können, damit auch andere Benutzer davon profitieren.