Ruby 2.0.0 リファレンスマニュアル > ライブラリ一覧 > cgi/sessionライブラリ
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 |