Ga naar inhoud

Redis & Sessies

Redis kan fungeren als een opslagprovider voor het cachen van sessie-gegevens zoals gebruikersgegevens.

Als er geen aangepaste RedisSessionsDelegate is opgegeven, zal er een standaard worden gebruikt.

Standaard Gedrag

SessionID Creatie

Tenzij je de makeNewID() methode implementeert in je eigen RedisSessionsDelegate, zullen alle SessionID waarden aangemaakt worden door het volgende te doen:

  1. Genereer 32 bytes van willekeurige tekens
  2. base64 codeer de waarde

Bijvoorbeeld: Hbxozx8rTj+XXGWAzOhh1npZFXaGLpTWpWCaXuo44xQ=

SessionData Opslag

De standaard implementatie van RedisSessionsDelegate slaat SessionData op als een eenvoudige JSON string waarde met behulp van Codable.

Tenzij u de makeRedisKey(for:) methode implementeert in uw eigen RedisSessionsDelegate, zal SessionData worden opgeslagen in Redis met een sleutel die de SessionID voorvoegt met vrs- (Vapor Redis Sessions)

Bijvoorbeeld: vrs-Hbxozx8rTj+XXGWAzOhh1npZFXaGLpTWpWCaXuo44xQ=

Registreren van een aangepaste delegatie

Om aan te passen hoe de data wordt gelezen van en geschreven naar Redis, registreer je je eigen RedisSessionsDelegate object als volgt:

import Redis

struct CustomRedisSessionsDelegate: RedisSessionsDelegate {
    // implementatie
}

app.sessions.use(.redis(delegate: CustomRedisSessionsDelegate()))

RedisSessionsDelegate

API Documentatie: RedisSessionsDelegate

Een object dat voldoet aan dit protocol kan worden gebruikt om te veranderen hoe SessionData wordt opgeslagen in Redis.

Slechts twee methoden hoeven te worden geïmplementeerd door een type dat voldoet aan het protocol: redis(_:store:with:) en redis(_:fetchDataFor:).

Beide zijn nodig, want de manier waarop u de sessiegegevens naar Redis schrijft, is intrinsiek verbonden met de manier waarop ze uit Redis moeten worden gelezen.

RedisSessionsDelegate Hash Voorbeeld

Als u bijvoorbeeld de sessiegegevens wilt opslaan als een Hash in Redis, dan zou u iets als het volgende implementeren:

func redis<Client: RedisClient>(
    _ client: Client,
    store data: SessionData,
    with key: RedisKey
) -> EventLoopFuture<Void> {
    // slaat elk gegevensveld op als een afzonderlijk hash-veld
    return client.hmset(data.snapshot, in: key)
}
func redis<Client: RedisClient>(
    _ client: Client,
    fetchDataFor key: RedisKey
) -> EventLoopFuture<SessionData?> {
    return client
        .hgetall(from: key)
        .map { hash in
            // hash is [String: RESPValue] dus we moeten proberen de
            // waarde uit te pakken als een string en elke waarde in de data container op te slaan
            return hash.reduce(into: SessionData()) { result, next in
                guard let value = next.value.string else { return }
                result[next.key] = value
            }
        }
}