コンテンツにスキップ

セッション

セッションを使用すると、複数のリクエスト間でユーザーのデータを永続化できます。セッションは、新しいセッションが初期化されたときに、HTTPレスポンスと共に一意のCookieを作成して返すことで機能します。ブラウザは自動的にこのCookieを検出し、将来のリクエストに含めます。これにより、Vaporはリクエストハンドラで特定のユーザーのセッションを自動的に復元できます。

セッションは、WebブラウザにHTMLを直接提供するVaporで構築されたフロントエンドWebアプリケーションに最適です。APIの場合は、リクエスト間でユーザーデータを永続化するために、ステートレスなトークンベース認証の使用をお勧めします。

設定

ルートでセッションを使用するには、リクエストがSessionsMiddlewareを通過する必要があります。これを実現する最も簡単な方法は、このミドルウェアをグローバルに追加することです。Cookieファクトリを宣言した後にこれを追加することをお勧めします。これは、Sessionsが構造体であるため、参照型ではなく値型だからです。値型であるため、SessionsMiddlewareを使用する前に値を設定する必要があります。

app.middleware.use(app.sessions.middleware)

ルートのサブセットのみがセッションを利用する場合は、代わりにSessionsMiddlewareをルートグループに追加できます。

let sessions = app.grouped(app.sessions.middleware)

セッションによって生成されるHTTP Cookieは、app.sessions.configurationを使用して設定できます。Cookie名を変更し、Cookie値を生成するためのカスタム関数を宣言できます。

// Cookie名を"foo"に変更します。
app.sessions.configuration.cookieName = "foo"

// Cookie値の作成を設定します。
app.sessions.configuration.cookieFactory = { sessionID in
    .init(string: sessionID.string, isSecure: true)
}

app.middleware.use(app.sessions.middleware)

デフォルトでは、VaporはCookie名としてvapor_sessionを使用します。

ドライバー

セッションドライバーは、識別子によってセッションデータの保存と取得を担当します。SessionDriverプロトコルに準拠することで、カスタムドライバーを作成できます。

Warning

セッションドライバーは、app.sessions.middlewareをアプリケーションに追加する_前に_設定する必要があります。

インメモリ

Vaporはデフォルトでインメモリセッションを利用します。インメモリセッションは設定が不要で、アプリケーションの起動間で永続化されないため、テストに最適です。インメモリセッションを手動で有効にするには、.memoryを使用します:

app.sessions.use(.memory)

本番環境での使用例については、データベースを使用してアプリの複数のインスタンス間でセッションを永続化および共有する他のセッションドライバーを確認してください。

Fluent

Fluentには、アプリケーションのデータベースにセッションデータを保存するサポートが含まれています。このセクションでは、Fluentを設定し、データベースに接続できることを前提としています。最初のステップは、Fluentセッションドライバーを有効にすることです。

import Fluent

app.sessions.use(.fluent)

これにより、アプリケーションのデフォルトデータベースを使用するようにセッションが設定されます。特定のデータベースを指定するには、データベースの識別子を渡します。

app.sessions.use(.fluent(.sqlite))

最後に、SessionRecordのマイグレーションをデータベースのマイグレーションに追加します。これにより、_fluent_sessionsスキーマにセッションデータを保存するためのデータベースが準備されます。

app.migrations.add(SessionRecord.migration)

新しいマイグレーションを追加した後、必ずアプリケーションのマイグレーションを実行してください。セッションはアプリケーションのデータベースに保存されるようになり、再起動間で永続化され、アプリの複数のインスタンス間で共有できます。

Redis

Redisは、設定されたRedisインスタンスにセッションデータを保存するサポートを提供します。このセクションでは、Redisを設定し、Redisインスタンスにコマンドを送信できることを前提としています。

セッションにRedisを使用するには、アプリケーションを設定するときに選択します:

import Redis

app.sessions.use(.redis)

これにより、デフォルトの動作でRedisセッションドライバーを使用するようにセッションが設定されます。

Seealso

RedisとSessionsの詳細については、Redis → Sessionsを参照してください。

セッションデータ

セッションが設定されたので、リクエスト間でデータを永続化する準備ができました。新しいセッションは、req.sessionにデータが追加されたときに自動的に初期化されます。以下の例のルートハンドラは、動的ルートパラメータを受け入れ、その値をreq.session.dataに追加します。

app.get("set", ":value") { req -> HTTPStatus in
    req.session.data["name"] = req.parameters.get("value")
    return .ok
}

以下のリクエストを使用して、名前Vaporでセッションを初期化します。

GET /set/vapor HTTP/1.1
content-length: 0

以下のようなレスポンスを受け取るはずです:

HTTP/1.1 200 OK
content-length: 0
set-cookie: vapor-session=123; Expires=Fri, 10 Apr 2020 21:08:09 GMT; Path=/

req.sessionにデータを追加した後、set-cookieヘッダーがレスポンスに自動的に追加されていることに注意してください。このCookieを後続のリクエストに含めることで、セッションデータにアクセスできます。

セッションから名前の値にアクセスするための以下のルートハンドラを追加します。

app.get("get") { req -> String in
    req.session.data["name"] ?? "n/a"
}

前のレスポンスからのCookie値を必ず渡しながら、以下のリクエストを使用してこのルートにアクセスします。

GET /get HTTP/1.1
cookie: vapor-session=123

レスポンスで名前Vaporが返されるのが確認できるはずです。必要に応じてセッションからデータを追加または削除できます。セッションデータは、HTTPレスポンスを返す前にセッションドライバーと自動的に同期されます。

セッションを終了するには、req.session.destroyを使用します。これにより、セッションドライバーからデータが削除され、セッションCookieが無効になります。

app.get("del") { req -> HTTPStatus in
    req.session.destroy()
    return .ok
}