HTTP::Session2でexpiresを設定する
自動ログイン機能を実装していて、最後のログインから1ヶ月間有効っていうのをやりたかった。
フレームワークにAmon2を使っていて、セッションの保存先はmemcacheを指定。
http://search.cpan.org/~tokuhirom/HTTP-Session2/
http://search.cpan.org/~kazeburo/Cookie-Baker-0.03/lib/Cookie/Baker.pm
上記ドキュメントを参照しつつ、以下の様に実装したけど
expiresは有効にならなかった(ブラウザ落とすと消える)。
sub session { my $c = shift; if (!exists($c->{session})) { $c->{session} = HTTP::Session2::ServerStore->new( env => $self->req->env, secret => 'PyQwUiCRqxnzUxAxbhBfdAFTTaVVHJjn', get_store => sub { Cache::Memcached::Fast::Safe->new( { servers => [ { address => 'localhost:11211' } ], namespace => 'app_session', }, ); }, session_cookie => +{ httponly => 1, secure => 0, name => 'has_session', path => '/', expires => '+1M', } ); } return $c->{session}; }
原因
finalize_plack_responseがレスポンスヘッダにCookieをぶち込んでいるけど
こいつはCookie::Baker::bake_cookieを使っていない。
cookieのexpiresにはそもそもGMT形式の日付を渡す必要があって、
bake_cookieが’+1M’を良しなに加工してくれている。
そのbake_cookieを使っていないということは、cookieには謎の’+1M’という文字が
わたっているだけだったのだ。
修正
じゃあ一ヶ月後の日付をGMTにして渡せば解決ってことで、
以下のようにしたら、うまいこと行った。
sub session { my $c = shift; if (!exists($c->{session})) { $c->{session} = HTTP::Session2::ServerStore->new( env => $self->req->env, secret => 'PyQwUiCRqxnzUxAxbhBfdAFTTaVVHJjn', get_store => sub { Cache::Memcached::Fast::Safe->new( { servers => [ { address => 'localhost:11211' } ], namespace => 'app_session', }, ); }, session_cookie => +{ httponly => 1, secure => 0, name => 'has_session', path => '/', } ); my $expires = time + (60*60*24*30); $c->{session}->session_cookie->{expires} = gmtime($expires); } return $c->{session}; }