Rubyでセッション管理2。

前々回の日記でRubyでセッション管理の方法を紹介しました。
今回はセッションを使ってログイン処理を作ってみたので、その覚え書き。

■環境
  • Ubuntu 7.04jp
  • Ruby 1.8.5
  • Apache 2.2.3
  • mod_ruby 1.2.6
■セッションを使ったログイン処理

セッションを使ってログイン処理を書くと、以下の点がHappyです。

  • ページを閉じてもログインしなおさなくてよい。
  • ページ間で情報(ユーザ名等)を共有できる


で、今回作る物の内容は以下のような感じ。

  1. ユーザ名とパスワードを入力してもらう
  2. パスワードがあっていればセッションを張る
  3. 次回以降、このページを訪れたときは保存されたユーザ名を表示する

※今回はパスワードは"foo"というパスワード固定にします。

これを日本語で書くと

セッション取得

if ログアウトボタンが押されたら
  セッション削除。
  このページにリダイレクト。
elsif セッションが存在していれば
  HTMLでユーザ名とログアウトボタンを表示。
elsif ユーザ名が入力され、パスワードがfooなら
  セッションを張る。
  セッション(Cookie)にユーザ名を保存。
  このページにリダイレクト。
else
  HTMLでログインページを表示
end

「このページにリダイレクト」という部分について説明しておきます。
これは以下の理由から行っています。
"フォームを送信した後に更新(F5)ボタンを押して、ページをリロードしたときに
フォームの再送が行われるのを防ぐため"
リダイレクトすることによって、フォームの値をなくしフォームの再送を
防いでいるのです。
ネットで調べた感じ、これしがベターなようです。
(もっといい方法があれば教えてください)


で、実際にRubyで書いてみます。
ファイル名はtest.rbxとします。

#!/usr/local/bin/ruby

require "cgi"
require "cgi/session"

cgi = CGI.new
begin
  session = CGI::Session.new(cgi,{"new_session"=>false})
rescue ArgumentError
  session = nil
end

if cgi['logout'] == "1"
  session.delete
  redirect_url="http://#{ENV['SERVER_NAME']}#{ENV['REQUEST_URI']}"
  header = cgi.header({"charset"=>"UTF-8","status"=>"REDIRECT","Location"=>redirect_url})
  puts header
elsif session != nil
  header = cgi.header("charset"=>"UTF-8")
  puts header
  puts <<-EOS
<html>
<head></head>
<body>
Hello #{session['name']}
<form action="test.rbx" method="post">
  <input type="submit" value="logout">
  <input type="hidden" name="logout" value="1">
</form>
</body>
</html>
  EOS
elsif cgi['name'] != "" and cgi['password'] == "foo"
  begin
    session = CGI::Session.new(cgi,{"new_session"=>false})
    session.delete
  rescue ArgumentError
  end

  session = CGI::Session.new(cgi,{"new_session"=>true})
  session['name'] = cgi['name']
  session.close

  redirect_url="http://#{ENV['SERVER_NAME']}#{ENV['REQUEST_URI']}"
  header = cgi.header({"charset"=>"UTF-8","status"=>"REDIRECT","Location"=>redirect_url})
  puts header
else
  header = cgi.header("charset"=>"UTF-8")
  puts header
  puts <<-EOS
<html>
<head></head>
<body>
<form action="test.rbx" method="post">
  <input type="text" name="name">
  <input type="password" name="password">
  <input type="submit" value="login">
</form>
  EOS
end

1つ注意点としては、フォームに値が入っていない場合
nilではなく""(空文字)が格納されています。
ですのでフォームの値が格納されているかどうかの条件式は以下のようになります。

...
if cgi['hoge'] != ""
  ...
end
...


今回はかなり手抜きでしたね。
ではでは。