任意のセッションIDを指定する。
CGI::Session を利用する場合に、デフォルトのセッションID生成ロジックは、CGI::Session::ID::md5 を利用しています。
CGI::Session
(snip) $self->{_DSN}->{id} ||= "md5"; (snip) "CGI::Session::ID::" . ($self->{_DSN}->{id} =~ /(.*)/)[0], (snip)
で、CGI::Session::ID::md5 のセッションID生成ロジックは以下のとおりです。
sub generate_id { my $md5 = new Digest::MD5(); $md5->add($$ , time() , rand(time) ); return $md5->hexdigest(); }
ここで着目するのが、md5の種にしている3つのパラメータです。
$$ - プロセスID
time() - 1970年1月1日からの経過秒数
rand(time) - 乱数
単一サーバで運用している場合は、プロセスIDと経過秒数がバッティングすることはありませんが、
複数サーバで運用した場合に上記がバッティングする可能性があります。
その場合に乱数値も同値になった場合にセッションIDが重複してしまいます。
その対処方法の1例を以下に挙げます。
1. セッションID生成クラスを新規作成する
内容は、md5.pm を元に、Sys::Hostname を use して、 md5 の種に、 hostname() を追加しています。
CGI::Session::ID::md5_for_multi_server
package CGI::Session::ID::md5_for_multi_server; use strict; use Digest::MD5; use Sys::Hostname; use CGI::Session::ErrorHandler; $CGI::Session::ID::md5_for_multi_server::VERSION = '1.0'; @CGI::Session::ID::md5_for_multi_server::ISA = qw( CGI::Session::ErrorHandler ); *generate = \&generate_id; sub generate_id { my $md5 = new Digest::MD5(); $md5->add($$ , time() , rand(time) , hostname()); return $md5->hexdigest(); } 1;
2. CGI::Session で md5_for_multi_server.pm を利用するように指定する。
Hoge.pm
my $session = CGI::Session->new( "driver:File;serializer:default;id:md5_for_multi_server", $self->cgiapp_get_query # CGI::Application を利用している );
これで複数サーバでもセッションIDが重複する可能性が無くなります。