やたら長いモジュール名になりますけども、CGI::Application::Plugin::Session を使うことで、ほとんど何も意識しないでもセッション管理ができるようになりました。
今のところ、Driver には mysql を使い、Serializer には Data::Dumper を使ってます。
CGI::Application::Plugin::Session を use すると、session_config が CGI::Application のメソッドとして生えるので、CGI::Application の初期化用フックメソッド cgi_appinit で、これを呼び出すだけです。ぼくの今の設定はこんなかんじ。
$self->session_config( CGI_SESSION_OPTIONS => ['driver:mysql', $self->query, { DataSource => $conf->{db}->{dsn}, User => $conf->{db}->{user}, Password => $conf->{db}->{password}, }], COOKIE_PARAMS => { -path => '/' }, DEFAULT_EXPIRY => '30m', SEND_COOKIE => 1 );
これだけで、セッションとかマジ意識しないでよくなった。
Driver
CGI::Application::Plugin::Session では、内部で CGI::Session を使ってるんですけど、その CGI::Session は Driver と Serializer を指定することで、セッション情報をどこに保存するか、どういう形で保存するかを決めることができます。
上の例だと、CGI_SESSION_OPTIONS で渡している 'driver:mysql' で Driver に mysql (実際には CGI::Session::Driver::mysql) を使うことを宣言してます。これは
$dbh->do("INSERT INTO " . $self->table_name . " ($self->{IdColName}, $self->{DataColName}) VALUES(?, ?) ON DUPLICATE KEY UPDATE $self->{DataColName} = ?", undef, $sid, $datastr, $datastr) or return $self->set_error( "store(): \$dbh->do failed " . $dbh->errstr );
ていう形で、mysql に保存してくれるみたい。セッション情報を格納するテーブル名やカラム名は自分で指定できるけど、デフォルトだと、テーブル名は sessions、カラム名は id と a_session です。というわけで、こういうテーブルを作っておけば良いです。
CREATE TABLE sessions ( id CHAR(32) NOT NULL PRIMARY KEY, a_session TEXT NOT NULL );
Serializer
Serializer は、セッション情報の格納形式を決めるものです。ぼくは指定してないんだけど、このときは CGI::Session::Serialize::default が使われる。この中では、実際には Data::Dumper でシリアライズがなされます。だから、sessions テーブルの中身はこんなかんじになる。
mysql> select * from sessions\G *************************** 1. row *************************** id: de8c2807a67f06ccfc15f65d58865b68 a_session: $D = {'_SESSION_ID' => 'de8c2807a67f06ccfc15f65d58865b68','_SESSION_ETIME' => 1800,'_SESSION_ATIME' => 1246782605,'_SESSION_EXPIRE_LIST' => {},'_SESSION_REMOTE_ADDR' => '::1','times' => 2,'_SESSION_CTIME' => 1246782603};;$D