Redis & Sessioni¶
Redis può fungere da provider di archiviazione per il caching dei dati di sessione come le credenziali degli utenti.
Se non viene fornito un RedisSessionsDelegate
personalizzato, sarà utilizzato quello di default.
Comportamento di Default¶
Creazione di SessionID¶
A meno che non implementi il metodo makeNewID()
nel tuo RedisSessionsDelegate
personale, tutti i valori SessionID
saranno creati facendo quanto segue:
- Generare 32 byte di caratteri casuali
- Codificare il valore in base64
Per esempio: Hbxozx8rTj+XXGWAzOhh1npZFXaGLpTWpWCaXuo44xQ=
Archiviazione di SessionData¶
L'implementazione di default di RedisSessionsDelegate
salverà SessionData
come una semplice stringa JSON usando Codable
.
A meno che non implementi il metodo makeRedisKey(for:)
nel tuo RedisSessionsDelegate
personale, SessionData
sarà salvato in Redis con una chiave che precede il SessionID
con vrs-
(Vapor Redis Sessions)
Per esempio: vrs-Hbxozx8rTj+XXGWAzOhh1npZFXaGLpTWpWCaXuo44xQ=
Registrare un Delegato Modificato¶
Per modificare il modo in cui i dati vengono letti e scritti su Redis, registra il tuo oggetto RedisSessionsDelegate
come segue:
import Redis
struct CustomRedisSessionsDelegate: RedisSessionsDelegate {
// implementazione
}
app.sessions.use(.redis(delegate: CustomRedisSessionsDelegate()))
RedisSessionsDelegate¶
Documentazione dell'API:
RedisSessionsDelegate
Un oggetto che è conforme a questo protocollo può essere usato per cambiare come SessionData
è salvato in Redis.
Viene richiesto di implementare solo due metodi a un tipo conforme al protocollo: redis(_:store:with:)
e redis(_:fetchDataFor:)
.
Entrambi sono necessari, in quanto il modo in cui tu personalizzi la scrittura dei dati di sessione su Redis è intrinsecamente legato a come deve essere letto da Redis.
Esempio di Hash di RedisSessionsDelegate¶
Per esempio, se vuoi salvare i dati di sessione come un Hash in Redis, dovresti implementare qualcosa simile a quanto segue:
func redis<Client: RedisClient>(
_ client: Client,
store data: SessionData,
with key: RedisKey
) -> EventLoopFuture<Void> {
// salva ogni campo dei dati come un campo hash separato
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 è [String: RESPValue] quindi dobbiamo provare e spacchettare il
// valore come una stringa e salvare ogni valore nel container dei dati
return hash.reduce(into: SessionData()) { result, next in
guard let value = next.value.string else { return }
result[next.key] = value
}
}
}