すき焼きの食材を買って帰ったはいいものの突然修正しなくてはいけないコードが降ってきまして〜 自炊する時間がなくてしょうがなく 最高のラーメン を食べたゆーすけべーです。
今回はMojoliciousのセッションについてのお話。もともと備わっているMojoliciousのセッションを使うにはこのような操作をします。
#!/usr/bin/env perl
use Mojolicious::Lite;
app->secret('passphrase');
get '/' => sub {
my $self = shift;
$self->session->{count}++;
$self->stash->{count} = $self->session->{count};
$self->render('index');
};
app->start();
__DATA__
@@ index.html.ep
Count: <%= $count %>
アクセスする度にカウントの数字が1増えます。簡単でしょ?ただ、ご存知かもしれませんが、Mojoliciousのセッションは…「keyとvalueのハッシュ構造をJSONにした文字列と secret
で設定したパスフレーズとをあわせたものをBase64にしてcookieぶっこんでいる」という仕様になっています。つまり
- ストア先はブラウザのcookieの値そのものに
- ブラウザcookieの値の長さ制限がある場合はそれに依存する
-
secret
が分かると中身が見れちゃう
ちょっとしたMojolicious::Liteを使ったアプリではこれでいかもですが、僕としては
- セッションIDだけをcookieとして保持
- 実際のデータストアはmemcachedとかredisに置きたい
という要望が出てきました。その際にわりと決定版な策は PSGI経由で立ち上げて Plack::Middleware::Session::Simple を使う方法です。従来まではPlack::Middleware::Sessionを使ってたり、独自にセッションマネージャを実装していましたが、Plack::Middleware::Sessionの場合CHIというちょっとファットなモジュールを介さないとmemcachedが使えなかったり、 自分でつくるとめんどかったりで一長一短でした。kazeburoさんが最近リリースしたPlack::Middleware::Session::Simpleは名前の通り実装がシンプルで依存関係も少ないのでオススメ。
上記の例をPlack::Middleware::Session::Simpleを使って書くなら helper
で psession
ってのを定義してこんな具合。
use Mojolicious::Lite;
use Plack::Builder;
use Cache::Memcached::Fast;
helper psession => sub {
my $self = shift;
my $env = $self->req->env;
return $env->{'psgix.session'};
};
get '/' => sub {
my $self = shift;
$self->psession->{count}++;
$self->stash->{count} = $self->psession->{count};
$self->render('index');
};
builder {
enable 'Session::Simple',
store =>
Cache::Memcached::Fast->new( { servers => [qw/127.0.0.1:11211/] } ),
cookie_name => 'myapp_session';
app->start();
};
__DATA__
@@ index.html.ep
Count: <%= $count %>
いい感じ〜 ちなみにPlack::Middlware::Session::Simpleのデータストアには「get/set/remove」メソッドが実装されているものならなんでもイケるのでredisとかへのラッパーを書けば他のデータストアも使えますねぇ〜
追記
kazeburoさんから指摘を受けて、Plack::Middleware::Sessionでもget/set/removeを実装すればCHI介さないで使えるとのこと。確かにCacheのインターフェスですからね。ってことで修正。ようは、よく出来たPlack::Middleware::*のセッション管理を使ってそれをMojoliciousでゴニョるってのがよいよーって話でした。