Passer au contenu

Redis et les sessions#

Redis peut agir en tant que stoquage pour mettre en cache les données de session comme les identifiants utilisateurs.

Si une instance personnalisée de RedisSessionsDelegate n’est pas fournie, une instance par défaut sera utilisée.

Comportement par défaut#

Création de SessionID#

À moins que vous n’implémentiez la méthode makeNewID() dans votre propre RedisSessionsDelegate, toutes les valeurs SessionID seront créées comme ceci :

  1. Génération de caractères aléatoires sur 32 octets

  2. Encodage en base64 de la valeur obtenue

Par exemple : Hbxozx8rTj+XXGWAzOhh1npZFXaGLpTWpWCaXuo44xQ=

Stoquage de SessionData#

L’implémentation par défaut de RedisSessionsDelegate stoquera les instances de SessionData comme simple chaîne JSON en utilisant Codable.

À moins que vous n’implémentiez la méthode makeRedisKey(for:) dans votre propre RedisSessionsDelegate, les données SessionData seront stoquées dans Redis avec une clé composée du préfixe vrs- (Vapor Redis Sessions) et de la valeur de SessionID.

Par exemple : vrs-Hbxozx8rTj+XXGWAzOhh1npZFXaGLpTWpWCaXuo44xQ=

Enregistrer un Delegate personnalisé#

Pour personnaliser la façon dont les données de Redis sont lues et écrites, enregistrez votre propre objet RedisSessionsDelegate comme ceci :

import Redis

struct CustomRedisSessionsDelegate: RedisSessionsDelegate {
    // implémentation
}

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

RedisSessionsDelegate#

Documentation de l’API : RedisSessionsDelegate

On peut utiliser un objet conforme à ce protocole pour modifier la façon dont les objets SessionData sont stoqués dans Redis.

Il n’y a que deux méthodes à implémenter pour un type se conformant au protocole : redis(_:store:with:) et redis(_:fetchDataFor:).

Les deux sont nécessaires, car la façon dont l’écriture des données dans Redis sera personnalisée est intrinsèquement liée à la façon dont elles doivent être lues depuis Redis.

Exemple de stoquage RedisSessionsDelegate en hash#

Par exemple, si vous vouliez stoquer vos données de session sous forme de hash dans Redis, vous implémenteriez quelque-chose similaire à ceci :

func redis<Client: RedisClient>(
    _ client: Client,
    store data: SessionData,
    with key: RedisKey
) -> EventLoopFuture<Void> {
    // Stoque chaque champ de données en champ hash distinct
    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
            // la variable hash est de type [String: RESPValue] donc nous devons tenter de déballer
            // la valeur sous le type string et stoquer chaque valeur du contenant.
            return hash.reduce(into: SessionData()) { result, next in
                guard let value = next.value.string else { return }
                result[next.key] = value
            }
        }
}
Modifier cette page