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値を設定しておこう。
ruby 1.8.2 feature: セッション情報ファイルは 0600 で作成されるようになった。
CGI::Session.new(cgi[, aHash])
セッションオブジェクトを新しく作成し返します。 オプションとして Hash オブジェクト aHash を与えることができる。 以下の文字列が aHash のキーとして認識される。
CGI::Session.new(cgi, {"new_session" => true})
クッキーのpathとして使われる。
(default: File.dirname(ENV["SCRIPT_NAME"])
,
スクリプトのURIのpath部の最後のスラッシュまで)
クッキーと<FORM type=hidden>のnameとして使われる。
(default: "_session_id"
)
セッションIDとして使われる。
デフォルトのデータベースであるFileStore
を用いる場合,
値は英数字だけからなる文字列で無ければならない。
このオプションが指定するとリクエストにセッションIDが含まれても無視される。
(default: ランダムに生成される)
値がtrueのときは強制的に新しいセッションを始める
以下は ruby 1.8.2 feature です。
値がfalseのときは、リクエストにセッションIDが含まれていない場合に 例外ArgumentErrorが発生する。
値がないときは、リクエストにセッションIDが 含まれている場合はそれを使用し、含まれていない場合は新しいセッションを始める.
(default: 値なし)
データベースクラス。
(defalut: CGI::Session::FileStore
)
CGI::Session::FileStore
がセッションデータを作成するディレクトリの名前
(default: ENV["TMP"] || "/tmp"
)
ruby 1.8 feature: default は Dir.tmpdir になりました。
CGI::Session::FileStore
がセッションデータのファイル名に与えるプレフィックス。
(default: ""
)
CGI::Session::FileStore
がセッションデータのファイル名に与えるサフィックス。
(default: ""
) ruby 1.8.2 feature
セッションの有効期間。 Timeオブジェクトを与えると、セッションはその日時まで破棄されずに残る。 (default: ブラウザの終了と同時に破棄される)
CGI::Session#[key]
指定されたキーの値を返します。
値が設定されていなければ nil を返します。
CGI::Session#[key] = val
指定されたキーの値を設定します。
CGI::Session#update
データベースクラスのupdate
メソッドを呼び出して、
セッション情報をサーバに保存します。
MemoryStore
の場合は何もしません。
CGI::Session#close
データベースクラスのclose
メソッドを呼び出して、
セッション情報をサーバに保存し、セッションストレージをクローズします。*2
CGI::Session#delete
データベースクラスのdelete
メソッドを呼び出して、
セッションをストレージから削除します。
FileStore
の場合はセッションファイルを削除します。
セッションファイルは明示的に削除しなければ残っています。
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
*1mod_ruby用って事かな...
*2 mod_ruby などで CGI::Session を利用する場合、明示的に close する必要がある。 参照→<URL:http://www.modruby.net/doc/faq.ja.jis.html#label-13>