Plack::Session::Store::File でできるだけセッションファイルを作らないようにする
Plack::Session::Store::File はお手軽でちょっとしたものを作りたいときに便利なんですが、いかんせんアクセスしただけでセッションファイルを作りまくるのは嫌なのでなんとかしたい、という話です
結論からいうと以下のようにすればいいようです。ここでは MessagePack を使ってますがシリアライザ自体は別になんでもよくて、serializer に指定するサブルーチンで、$session に値がなければ書きこまないようにしただけです。
この場合、セッションに値を一切入れない場合毎回セッションIDが変化する状態 (不定) になります。CSRF 対策なんかでセッションIDを流用している場合は、セッションIDを確定させるため POST 前の画面を開いた時点では、セッションに適当な値を書きこむ必要があります (セッションを使うところではセッションに値を書くことで明示的にそれを示す)。
my $MessagePack = Data::MessagePack->new;
$MessagePack->canonical;
builder {
enable "Plack::Middleware::Session",
state => Plack::Session::State::Cookie->new(
session_key => 's',
expires => 60 * 60 * 24 * 365,
),
store => Plack::Session::Store::File->new(
dir => config->root->subdir('session').q(),
serializer => sub {
my ($session, $file) = @_;
return unless %$session;
my $fh = file($file)->openw;
print $fh $MessagePack->pack($session);
close $fh;
},
deserializer => sub {
my ($file) = @_;
eval {
$MessagePack->unpack(scalar file($file)->slurp)
} || +{}
},
);
$app;
|;