任意のセッション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生成ロジックは以下のとおりです。

CGI::Session::ID::md5

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が重複する可能性が無くなります。