Play でのセッションは Cookie として実現されている。
Play でセッションを使う場合にはこのようなコードになる。
package controllers import play.api._ import play.api.mvc._ import play.api.mvc.RequestHeader object Application extends Controller { def index = Action.apply { request => val currentVal : String = request.session.get("hoge") match { case Some(x) => x; case None => ""; } Ok("hoge = " + currentVal).withSession( request.session + ("hoge" -> "hogege")); } }
request.session.get
は Option を返すので、
パターンマッチで Some
か None
かを判定して、Some
から値を取り出す必要がある。もしくは、Option.getOrElse を使って、
... val currentVal : String = request.session.get("hoge").getOrElse(""); ...とする。こっちの方が簡単でいい。
レスポンスヘッダ
このApplication へのアクセスの Response ヘッダは以下のようになっている。
Content-Length:7 Content-Type:text/plain; charset=utf-8 Set-Cookie:PLAY_SESSION=086cb3ef28d787e60a6a1dfd4f880c201de6521e-hoge%3Ahogege;Path=/;HTTPOnly
PLAY_SESSION という Cookie に Application でセッションにセットした値がそのまま入っている。
したがって、セッションに保持できるのは 文字列にした情報のみで あまり長い値を保持することはできない (RFC-2965 によると 少なくとも1Cookie あたり 4096 バイトまで実装せよ、とのことなのでそれ以上は保証されない)。
また、サーバー側でセットした値がそのまま平文で繰り返し流されることになるので秘密情報を載せることもできない。
PLAY_SESSION
クッキーは編集不可
PLAY_SESSION
クッキーの前半部分の文字列は署名になっているらしく、
PLAY_SESSION
クッキーの値をクライアント側で勝手に編集すると、
Play側ではPLAY_SESSION
クッキーはなかったものと扱われる。
実際に Chrome の Edit This Cookie Plugin 等を使って値を編集すると Play 側で値を取得できない。
Request Header .... Cookie:PLAY_SESSION=086cb3ef28d787e60a6a1dfd4f880c201de6521e-hoge%3Ahogaga Host:localhost:9000 .... Applicationの表示 hoge =
クライアント側で
PLAY_SESSION
クッキーの hoge 値を編集したものが リクエストヘッダに乗っかっているが、Application では この値は取得されない。
PLAY_SESSION
を HTTPSession のように使いたいのなら Cache を使う。
HTTPSession のように Cookie に保持できない値は サーバー側で保持するなら play.api.Cache を使う。
package controllers import play.api._ import play.api.cache._ import play.api.mvc._ import play.api.mvc.RequestHeader object Application extends Controller { def index = Action.apply { request => var sessionId : String = request.session.get("id") match { case Some(x) => x; case None => java.util.UUID.randomUUID().toString(); } import play.api.Play.current; var value : String = Cache.get(sessionId) match { case Some(x) => Cache.set(sessionId, x, 10); x.asInstanceOf[String]; case None => Cache.set(sessionId, "hoge", 10); ""; } Cache.set(sessionId + "hoge", "hogege", 10); Ok("value = " + value).withSession( request.session + ("id" -> sessionId)); } }
Cache を使う際には、「import play.api.Play.current」を入れておかないとエラーになる。
You do not have an implicit Application in scope. If you want to bring the current running Application into context, just add import play.api.Play.current
Play の セッションには位置な識別子がないので、UUIDなどを自分で生成して Session に格納しておく。
Cache にセットする際には Expire(秒)が指定できるが、「取得しただけでは更新されない」ので、 毎回、新たにセットしなおして更新しないと、最初に入れてから Expire 時間が過ぎると 期限切れでなくなってしまう。
0 件のコメント:
コメントを投稿