Last active
August 29, 2015 14:20
-
-
Save worthmine/2f69754bf80fd9c9d044 to your computer and use it in GitHub Desktop.
[Perl] CGI::Session でログイン/ログアウトを管理する簡単なサンプル ref: http://qiita.com/worthmine/items/22380ee826991277f5c5
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/local/bin/perl | |
use strict; | |
use warnings; | |
# 注)環境依存。この辺は適当に変えてください | |
use lib "$ENV{DOCUMENT_ROOT}/lib/perl5"; # CPANモジュールを読み込む | |
use lib "$ENV{DOCUMENT_ROOT}/lib"; # 上位のモジュールを読み込む | |
use lib "./lib"; # ローカルなモジュールを読み込む | |
# 環境依存終了 | |
use CGI qw|:standard|; | |
use CGI::Session; #qw|-ip_match|; #WiFiとモバイルの切り替えを考えると、IPアドレスが同一とは限らない | |
use Password; | |
my $title = "セッションID管理テスト"; | |
my $expire = '+1h'; | |
my $encode = 'UTF-8'; | |
# 本当はデータベースを使うところを省略 | |
my %User = ( 'Qiita' => { pass => q|$1$hEeN3T%+$CRKHRxko1cWGNjE69mTNw.| } ); | |
my $cgi = new CGI; | |
# GETリクエストによるセッションIDの指定の無効化 | |
print $cgi->redirect( -uri=>'http://'.$ENV{SERVER_NAME}.$ENV{SCRIPT_NAME}, -status=>301 ) and exit if $cgi->param('CGISESSID'); | |
my $sid = $cgi->cookie('CGISESSID') || undef; | |
# 1.cookieからCGISESSIDを探す | |
# 2.取得できなかったらundef. | |
my $session = CGI::Session->load(undef, $sid, {Directory=>'./data'}) or die CGI::Session->errstr(); | |
Error("Your session timed out! Refresh the screen to start new session!") if $session->is_expired; | |
$session->expire($expire); # 有効期限の設定 | |
#$session->expire('+1m'); # テスト用 | |
if ( $session->is_empty ) { | |
$session = $session->new(undef, $sid, {Directory=>'./data'}) or die $session->errstr; | |
}# 3.取得したセッションidが有効ならそのまま.無効なら別のidを発番. | |
my %param = $cgi->Vars(); | |
my @message; | |
if ($session){ | |
if (my $action = $param{'action'}){ | |
push @message, forget() if $action eq 'forget me'; # セッションの削除依頼 | |
push @message, logout() if $action eq 'logout'; # セッション内のログインステータスを初期化 | |
} | |
$session->save_param($cgi); # 入力値をセッション内に保存 | |
$session->clear('pass'); # パスワードの平文保存を回避 | |
push @message, login($session->param('username'), $param{'pass'} ) if $param{'action'} and $param{'action'} eq 'login'; | |
push @message, $session->param('username')? confirm(): ask(); # 有効なIDを持つセッション | |
}else{ | |
push @message, ask(); | |
} | |
print $session->header( -charset => $encode ), | |
start_html( -title => $title, -encoding => $encode, -lang => 'ja'), | |
@message, | |
a({href=>$ENV{"SCRIPT_NAME"}}, '戻る',), | |
end_html(), | |
; | |
exit; | |
sub Error { | |
my $msg = shift; | |
print $session->header( -charset => $encode ), | |
start_html( -title => "エラー / " . $title, -encoding => $encode, -lang => 'ja'), | |
h1("エラー"),hr(), | |
p(strong($msg)),hr(), | |
a({href=>$ENV{"SCRIPT_NAME"}}, '戻る',), | |
end_html(), | |
; | |
exit; | |
} | |
sub forget { | |
$session->clear(['username', 'firstname', 'lastname', 'like', 'action', 'login']); | |
$session->close; | |
$session->delete; | |
return h2("We've forgotten you!"); | |
} | |
sub login { | |
my ($id, $pass ) = @_; | |
Error("存在しないユーザー名でのログインが試行されました: $id\n") if not exists $User{$id}; | |
Error("$idのパスワードが違います\n") if not Password->verify( $pass, $User{$id}{'pass'} ); | |
$session->param('login', 1); | |
$session->clear('pass'); | |
$session->expire('login', '+1w'); | |
return h2("ログイン成功!"), | |
} | |
sub logout { | |
$session->param('login', 0); | |
return h2("ログアウト成功!"); | |
} | |
sub ask{ #セッションからユーザーデータを取得できない場合の挙動 | |
return h1("We don't know who you are."), | |
start_form(), p( | |
'your first name', textfield('firstname', $session->param('firstname'), 16, 16), br(), | |
'your last name', textfield('lastname', $session->param('lastname'), 16, 16), br(), | |
'your unique ID', textfield('username', $session->param('username'), 16, 16), br(), | |
'tell me what you like', textfield('like', $session->param('like'), 16, 16), br(), | |
submit('action', 'register'), | |
),end_form(); | |
} | |
sub confirm { | |
$session->expire('+1y'); | |
my @confirm; | |
if ( $session->param('login') != 1) { | |
push @confirm, | |
password_field('pass',undef,16,20),'password is allowed 4-20 charctors', br(), | |
submit('action', 'login'), "or", | |
; | |
}else{ | |
push @confirm, | |
'your first name is ',$session->param('firstname'), br(), | |
'your last name is ',$session->param('lastname'), br(), | |
'your favorite is ',$session->param('like'), br(), | |
'and your last action is ',$session->param('action'), br(), | |
submit('action', 'logout'), "or",submit('action', 'refresh'), "or", | |
; | |
} | |
return | |
h1(a( {href=>"$ENV{'SCRIPT_NAME'}?CGISESSID=".$session->id()}, "We know who you are,", $session->param('username') )), | |
start_form(), | |
p(@confirm, submit('action', 'forget me'),), | |
end_form(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment