Redis & セッション¶
Redisはセッションデータ(ユーザー認証情報など)をキャッシュするためのストレージプロバイダーとして機能します。
カスタムのRedisSessionsDelegate
が提供されない場合、デフォルトのものが使用されます。
デフォルトの動作¶
SessionIDの作成¶
独自のRedisSessionsDelegate
でmakeNewID()
メソッドを実装しない限り、すべてのSessionID
値は以下の手順で作成されます:
- 32バイトのランダムな文字を生成
- その値をbase64エンコード
例:Hbxozx8rTj+XXGWAzOhh1npZFXaGLpTWpWCaXuo44xQ=
SessionDataの保存¶
RedisSessionsDelegate
のデフォルト実装は、SessionData
をCodable
を使用してシンプルなJSON文字列値として保存します。
独自のRedisSessionsDelegate
でmakeRedisKey(for:)
メソッドを実装しない限り、SessionData
はSessionID
にvrs-
(Vapor Redis Sessions)というプレフィックスを付けたキーでRedisに保存されます。
例:vrs-Hbxozx8rTj+XXGWAzOhh1npZFXaGLpTWpWCaXuo44xQ=
カスタムデリゲートの登録¶
Redisへのデータの読み書き方法をカスタマイズするには、独自のRedisSessionsDelegate
オブジェクトを以下のように登録します:
import Redis
struct CustomRedisSessionsDelegate: RedisSessionsDelegate {
// 実装
}
app.sessions.use(.redis(delegate: CustomRedisSessionsDelegate()))
RedisSessionsDelegate¶
APIドキュメント:
RedisSessionsDelegate
このプロトコルに準拠するオブジェクトを使用して、SessionData
がRedisに保存される方法を変更できます。
プロトコルに準拠する型が実装する必要があるメソッドは2つのみです:redis(_:store:with:)
とredis(_:fetchDataFor:)
。
セッションデータをRedisに書き込む方法のカスタマイズは、Redisからデータを読み取る方法と本質的に関連しているため、両方とも必須です。
RedisSessionsDelegateハッシュの例¶
例えば、セッションデータをRedisのハッシュとして保存したい場合、以下のような実装を行います:
func redis<Client: RedisClient>(
_ client: Client,
store data: SessionData,
with key: RedisKey
) -> EventLoopFuture<Void> {
// 各データフィールドを個別のハッシュフィールドとして保存
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]なので、値を文字列として
// アンラップして各値をデータコンテナに保存する必要があります
return hash.reduce(into: SessionData()) { result, next in
guard let value = next.value.string else { return }
result[next.key] = value
}
}
}