頭がごちゃごちゃしてきたので、頭の整理も兼ねて書いてみる。
CGIでセッション管理を行うのは少々面倒くさいので、CGI::Sessionモジュールを使ってやる。
セッションを読み込むのは、CGIオブジェクトをCGI::Sessionに渡してやるだけ。
my $cgi = CGI->new;
my $session = CGI::Session->new("dr:MySQL", $cgi, {Handle => $dbh});
もし、読み込めなければ、新しくセッションを作ることになる。
読み込まれた(または新しく作られた)セッションはcookieかformに保存してやる。
どちらに保存しても、CGIオブジェクトを渡せば取得できる。
鍵になる名前は決まっているけど、nameメソッドを使ってやったほうが確実。
$cgi->append(
-name => 'new_cookie',
-value => [
$cgi->cookie(
-name => $session->name,
-value => $session->id,
-expires => '+28d',
),
],
);
CGI.pmのメソッドであるappendを使っているのは、あとでまとめてcookieを保存させるため。
出力する時は以下のような感じにする。
print $cgi->header(
-cookie => [$cgi->param("new_cookie")],
);
話を戻す。
CGIオブジェクトから取得できた時点で、CGI::Sessionによってデータの照合が行われる。
セッションに何らかの情報を保存していて、その情報が取得できれば認証できたということ。
得られなければ新しく作られたか、認証に失敗したという事になる。
セッションの実体はサーバー側にある。
先の例の場合は、MySQLというデータベースにセッションの情報を保管している。
クライアントとのやりとりはIDだけ。
IDは少なくともサーバー側でユニークなので、他の人のデータになってしまうことはまずない。
これに加えて、IP情報と一緒に管理する方法もある。
use CGI::Session qw(-ip_match);
チュートリアルなどには「"-ip-match"スイッチ」と書いてあるのだが、ソースを見ると「-ip_match」が正しい。
IDが同じでIPアドレスが違うという状況でテストしたら、サーバーに保管してあるセッション情報が削除された。
つまり、IDを何らかの方法で知ったとしても、IPアドレスが違うため使用できない、という事が確認できた。
逆に、IPアドレスが同じで違うIDの場合は、サーバー側にIDが貯まっていく。
セッションを削除せずに新しいIDを発行するとどんどん増えていく。
元々、多重登録を防止するため、アクティブなIPアドレスは一つしかセッションを持てないような仕組みにしていた。
IP情報と一緒に管理する、というのを見て乗り換えたつもりだったのだがそこだけが失敗。
