LoginSignup
4
1

More than 5 years have passed since last update.

Yesodでセッション情報をDBに格納するようにする

Last updated at Posted at 2016-03-29

Yesodが作ってくれるテンプレートプロジェクトでは、セッション情報をファイルに格納するようになっている。
しかしロードバランサ環境ではこれでは困るので、DBに格納するようにしたい。

Yesodでのセッションの実装を差し替える方法は存在していて、本エントリではその方法を紹介する。

2つのモジュール

次の2つのモジュールがキモ。

(リンク先はGitHubにしてあります)

使い方が書いてあるドキュメントがなかなか見つからなかったので結局ソースのコメントを見て探った。

2016.3.31追記
この辺りのモジュールの構成の意味を解説しているQiitaの記事がありました。ありがたいです。

ソースの修正

cabalファイル

cabalのbuild-dependsに次を追記。

, serversession
, serversession-frontend-yesod
, serversession-backend-persistent

スキーマをMigrateする処理を変える

セッション情報をDBに格納するにはスキーマのMigrate処理でテーブルを作る必要がある(蛇足だが、MongoDBの場合は不要な処理だと思う)。

まずModel.hsを修正。

修正前)

Model.hs
share [mkPersist sqlSettings, mkMigrate "migrateAll"]
    $(persistFileWith lowerCaseSettings "config/models")

修正後)

Model.hs
share [mkPersist sqlSettings, mkSave "entityDefs"]
    $(persistFileWith lowerCaseSettings "config/models")

mkMigrate 関数を後で呼び出すので、ここではmodelsファイルのパース結果をentityDefsに束縛するようにする(mkMigrateは2回呼び出すとエラーになるので)。

なおimportのmkMigratemkSaveに変更するのを忘れずに。

次にApplication.hsに、セッション情報格納用のスキーマを定義する処理を追記する。

Applicatino.hs
import qualified Data.Proxy as P
import qualified Web.ServerSession.Core as SS
import qualified Web.ServerSession.Backend.Persistent as SS

-- Create migration function using both our entities and
-- serversession-backend-persistent ones.
mkMigrate "migrateAll" (SS.serverSessionDefs (P.Proxy :: P.Proxy SS.SessionMap) ++ entityDefs)

ここでやっていることは、予めパースしておいたconfig/modelsの結果とセッション情報を格納するスキーマ情報を結合した上でMigrateする、という処理。

sessionBackendの実装を差し替える

ストレージにセッションを格納するようにFoundation.hsを修正する。
まずはimportを追加。

Foundation.hs
import Web.ServerSession.Backend.Persistent
import Web.ServerSession.Frontend.Yesod

Yesodクラスのインスタンスにする際のmakeSessionBackend関数の実装を変更する。

Foundation.hs
-- | Cookie name used for the sessions of this example app.
sessionCookieName :: Text
sessionCookieName = "SESSION"
Foundation.hs
    makeSessionBackend = simpleBackend opts . SqlStorage . appConnPool
      where opts = setIdleTimeout     (Just $  5 * 60) -- 5  minutes
                 . setAbsoluteTimeout (Just $ 20 * 60) -- 20 minutes
                 . setCookieName      sessionCookieName

セッションタイムアウトの数値は適当に変更してください。

課題

セッション情報を格納するDBとアプリケーション情報を格納するDBを分けたい、という要件があると思うので、これに対処する方法を今後検討したい。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1