CGI のセッション管理を行うライブラリ。
セッションとは、HTTP の一連のリクエストとレスポンスが属するべきコンテクスト (状況) のことをいいます。セッション管理には従来通り cgi ライブラリが提供するクッキーを使用してもいいですが、この cgi/session を使用した方がよりわかりやすいでしょう。セッション情報は Hash ライクなインターフェースです。
セッションはセッション ID とプログラムが記録したセッション情報から構成されます。デフォルトでは CGI::Session::FileStore が使用され、記録できるのは文字列のみです。
セッション情報は CGI::Session::FileStore か CGI::Session::PStore を使用した場合はサーバのローカルファイルに記録され、次回のリクエスト時に利用されます。デフォルトでは明示的に操作を行なわなくてもプログラム終了時にセッション情報はファイルに保存されます。セッション毎に新しいファイルが作成されます。
クライアントにはセッション情報に対応するセッション ID をクッキーあるいは form の hidden input として渡すことになります。クッキーはデフォルトでは expires が指定されていないために、ブラウザを終了した時点で消滅します。
require 'cgi/session' cgi = CGI.new session = CGI::Session.new(cgi)
CGI::Session.new に CGI オブジェクトを渡します。クライアントから渡されたセッション ID はクッキーかクエリーとして cgi に格納されているため、意識する必要はありません。
session['name'] = "value"
CGI::Session オブジェクトは Hash のようなもので、キーに対応する値を記録します。デフォルトではプログラム終了時にセッション情報はファイルに記録されます。
name = session['name']
別な CGI でこのセッション情報を取り出すときは、このようにします。
ヘッダ出力は CGI#out、CGI#header を使っている限り通常通りで構いません。 cgi/session は内部的にクッキーを使用していますが、これらのメソッドが面倒を見てくれるので、意識をする必要はありません。
umask 値が 0022 ならばセッション情報ファイルのパーミッションが 644 になるので、任意のユーザがそのセッション情報ファイルを見ることができます。それが嫌な場合は CGI::Session オブジェクト生成前に umask 値を設定してください。
セッション情報ファイルは 0600 で作成されるようになりました。
CGI::Session.new 後の CGI::HtmlExtension#form は、セッション ID を埋め込んだ隠しフィールドを自動出力するようになります。 CGI::Session.new は、これによって生成されたフォームフィールド値を、セッション ID として自動認識します。
CGI::HtmlExtension#form を使い、<INPUT TYPE="submit"> でページ遷移をするようにすれば、クッキーが使えない環境でのセッション維持に利用できます。
#!/usr/bin/ruby require 'cgi' require 'cgi/session' cgi = CGI.new('html3') File.umask(0077) session = CGI::Session.new(cgi) cgi.out('charset'=>'euc-jp') { html = cgi.html { cgi.head { cgi.title {'Form Demo'} } cgi.body { cgi.form('action'=>"#{CGI.escapeHTML(cgi.script_name)}") { cgi.p { 'あなたの名前は?' + cgi.text_field('name') + cgi.hidden('cmd', 'hello') + cgi.submit('です。') } } } } CGI.pretty(html) } #=> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <HTML> <BODY> <FORM METHOD="post" ENCTYPE="application/x-www-form-urlencoded" action="/sample.rb"> <P> あなたの名前は? <INPUT NAME="name" SIZE="40" TYPE="text"> <INPUT NAME="cmd" TYPE="hidden" VALUE="hello"> <INPUT TYPE="submit" VALUE="です。"> </P> <INPUT TYPE="HIDDEN" NAME="_session_id" VALUE="bc315cc069266e21"> # これ </FORM> </BODY> </HTML>
ただ名前を入力するとあいさつをするだけのつまらない CGI スクリプト。
ソースコード
#!/usr/bin/ruby require 'kconv' require 'cgi' require 'cgi/session' class SessionDemo def initialize @cgi = CGI.new File.umask(0077) # セッションファイルは誰にも読まれたくないよ @session = CGI::Session.new(@cgi) # セッションはこうして生成する。 @cmd = "#{@cgi['cmd'].first}" # ruby 1.8 でも動くように(warning は出ます) @cmd = 'start' if @cmd.empty? @header = { "type" => "text/html", "charset" => "euc-jp" } __send__("cmd_#{@cmd}") end def cmd_start @cgi.out(@header) { <<-END <html><head><title>CGI::Session Demo</title></head> <body> <form action="#{CGI.escapeHTML(ENV['SCRIPT_NAME'])}" method="get"> <p> あなたの名前は? <input type="text" name="name"> <input type="hidden" name="cmd" value="hello"> <input type="submit" value="です。"> </p> </form> </body></html> END } end def cmd_hello name = Kconv.toeuc(@cgi['name'].first) @session['name'] = name # セッションに記憶 @cgi.out(@header) { # セッション情報は隠れクッキーで保持されるため、CGI#outで出力 <<-END <html><head><title>CGI::Session Demo</title></head> <body> <p>こんにちは、#{CGI.escapeHTML(name)}さん</p> <p><a href="#{CGI.escapeHTML(ENV['SCRIPT_NAME'])}?cmd=bye">[次へ]</a></p> </body></html> END } end def cmd_bye name = @session['name'] # セッションデータから取り出し @cgi.out(@header) { <<-END <html><head><title>CGI::Session Demo</title></head> <body> <p>#{CGI.escapeHTML(name)}さん、さようなら</p> <p><a href="#{CGI.escapeHTML(ENV['SCRIPT_NAME'])}">[戻る]</a></p> </body></html> END } end end SessionDemo.new
CGI::Session | |
CGI::Session::FileStore | File を用いたセッション保存先を表すクラスです。 |
CGI::Session::MemoryStore | セッションの保存先としてメモリを使用するクラスです。 |
CGI::Session::NullStore | セッションの状態をどこにも保存しないクラスです。 |
CGI::Session::NoSession | セッションが初期化されていない場合に発生する例外です。 |
cgi/session/pstore |