ユーザ認証とセッション
Copyright(C) 25Feb2014 coskx TNCT
sha256,セッションの利用 PHPサンプル <?php
function makeA1($userID,$pass,$realm) //sha256でダイジェストする
{
return hash('sha256', $userID . ":" . $realm . ":" . $pass);
}
function getPASSWD_A1($userID)
{
global $mydatabase;
if ($userID==$mydatabase['userID']) return $mydatabase['A1'];
else return FALSE;
}
////////// ここからphpメイン ///////////////////////
$userID="TokyoTaro";
$password="himitsudesu";
$realm = 'Restricted area';
$A1=makeA1($userID,$password,$realm);
$mydatabase['userID']=$userID;
$mydatabase['A1']=$A1;
//本当は$A1はあらかじめ求められて,ファイルなどに保存されている。
$pagetoshow=0; //0:loginページを表示,1:メニューメージ(セッション開始),999:logout作業 2以降は必要に応じて定義
$message="";
if (isset($_POST['login']) && isset($_POST['userID']) && isset($_POST['userPASS']) && isset($_POST['realm']) && isset($_POST['nonce'])) { //ログインボタンが押された
//$_POST['userPASS']はA1ダイジェストされた文字列が来る
$message="login受け付けました。 ";
$strcheck=TRUE;
if (!preg_match('/\A([0-9A-Fa-f])+\Z/',$_POST['userPASS'])) $strcheck=FALSE;
if (!preg_match('/\A([0-9A-Za-z_ ])+\Z/',$_POST['realm'])) $strcheck=FALSE;
if (!preg_match('/\A([0-9A-Fa-f])+\Z/',$_POST['nonce'])) $strcheck=FALSE;
$userID = htmlspecialchars($_POST['userID'], ENT_QUOTES);
if (!preg_match('/\A([0-9A-Za-z_ ])+\Z/',$userID)) $strcheck=FALSE;
if ($strcheck===TRUE) {
$A1=getPASSWD_A1($userID);
if ($A1!==FALSE) {
$A2= hash('sha256', $_POST['nonce'] . ":" . $A1);
if ($_POST['userPASS']===$A2) { //認証された
$message .= $userID . "さん 認証に成功しました。";
$pagetoshow = 1;
session_start();
//セッションを作成する
$_SESSION["userID"] = $userID; //サーバに値を保存
$date = date('c');
$message .= 'セッションをオープンしました。';
} else {
$message .= $userID . "さん 認証に失敗しました。もう一度やり直してください";
}
} else {
$message .= $userID . "さんは未登録のユーザです";
}
} else {
$message .= "認証できません";
}
} else if (isset($_POST['menupage']) && isset($_COOKIE[session_name()]) ) { //選択ボタンが押された
session_start();
$userID = $_SESSION["userID"];
$pagetoshow=1;
} else if (isset($_POST['work1']) && isset($_COOKIE[session_name()]) ) { //作業1ボタンが押された
session_start();
$userID = $_SESSION["userID"];
$pagetoshow=101;
} else if (isset($_POST['work2']) && isset($_COOKIE[session_name()]) ) { //作業2ボタンが押された
session_start();
$userID = $_SESSION["userID"];
$pagetoshow=102;
} else if (isset($_POST['work3']) && isset($_COOKIE[session_name()]) ) { //作業3ボタンが押された
session_start();
$userID = $_SESSION["userID"];
$pagetoshow=103;
} else if (isset($_POST['logout'])) { //ログアウトボタンが押された
session_start();
//既存のセッションを使用可能にする
$pagetoshow=999;
if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), '', time() - 1800, '/');
} // cookieの削除
session_destroy(); //セッションの終了
$message .= 'ログアウトしました。';
} else {
//初回は必ずここを通過する
$pagetoshow=0;
$message="ユーザの認証をします";
}
?>
<html>
<head>
<script src="./sha256.js"></script>
<script type="text/javascript">
<!--
function SubmitIdPass() {
var tmp1=document.frm_login.userID.value
+":"+document.frm_login.realm.value
+":"+document.frm_login.userPASS.value;
var shaObj1=new jsSHA(tmp1, "ASCII");
var sha256digest1 = shaObj1.getHash("SHA-256", "HEX");
var tmp2=document.frm_login.nonce.value+":"+sha256digest1;
var shaObj2=new jsSHA(tmp2, "ASCII");
var sha256digest2 = shaObj2.getHash("SHA-256", "HEX");
document.frm_login.userPASS.value=sha256digest2;
document.frm_login.submit();
}
// -->
</script>
</head>
<body>
<h1>sha256 sessionテスト</h1>
<?php if ($pagetoshow==0) { ?>
<?php print $message; ?>
<p>
あなたのユーザIDとパスワードを入力して,ログインボタンを押してください。<br><br>
</p>
<form name="frm_login" method="post">
ユーザID <input type="text" name="userID"><br>
パスワード <input type="password" name="userPASS"><br>
<input type="hidden" name="realm" value="<?php echo $realm; ?>">
<input type="hidden" name="nonce" value="<?php echo uniqid(); ?>">
<input type="hidden" name="login" value="">
<input type="button" onclick="SubmitIdPass();" name="" value="ログイン" >
</form>
<?php } else if ($pagetoshow==1) { ?>
<?php
print "こんにちは,<b>" . $userID . "</b>さん。<br>\n";
print $message;
?>
<p>
作業を選択してください。<br>
<form method="post">
<input type="submit" name="work1" value="作業1"> 作業1を行います。<br>
</form>
<form method="post">
<input type="submit" name="work2" value="作業2"> 作業2を行います。<br>
</form>
<form method="post">
<input type="submit" name="work3" value="作業3"> 作業3を行います。<br>
</form>
<form method="post">
<input type="submit" name="logout" value="ログアウト"><br>
</form>
<?php } else if ($pagetoshow==101) { ?>
<?php
print "こんにちは,<b>" . $userID . "</b>さん。<br>\n";
print $message;
?>
<p>作業1<br> :<br> :<br></p>
<form method="post">
<input type="submit" name="menupage" value="作業選択">
</form>
<form method="post">
<input type="submit" name="logout" value="ログアウト"><br>
</form>
<?php } else if ($pagetoshow==102) { ?>
<?php
print "こんにちは,<b>" . $userID . "</b>さん。<br>\n";
print $message;
?>
<p>作業2<br> :<br> :<br></p>
<form method="post">
<input type="submit" name="menupage" value="作業選択">
</form>
<form method="post">
<input type="submit" name="logout" value="ログアウト"><br>
</form>
<?php } else if ($pagetoshow==103) { ?>
<?php
print "こんにちは,<b>" . $userID . "</b>さん。<br>\n";
print $message;
?>
<p>作業3<br> :<br> :<br></p>
<form method="post">
<input type="submit" name="menupage" value="作業選択">
</form>
<form method="post">
<input type="submit" name="logout" value="ログアウト"><br>
</form>
<?php } else if ($pagetoshow==999) { ?>
<p>
ログアウトしました。<br>
</p>
<?php } ?>
</body>
</html>
こちらの例ではユーザ認証のためのセッションを生成している。
sha256を用いたユーザ認証とセッション生成の例
<?php
function makeA1($userID,$pass,$realm) //sha256でダイジェストする
{
return hash('sha256', $userID . ":" . $realm . ":" . $pass);
}
function getPASSWD_A1($userID)
{
global $mydatabase;
if ($userID==$mydatabase['userID']) return $mydatabase['A1'];
else return FALSE;
}
////////// ここからphpメイン ///////////////////////
$userID="TokyoTaro";
$password="himitsudesu";
$realm = 'Restricted area';
$A1=makeA1($userID,$password,$realm);
$mydatabase['userID']=$userID;
$mydatabase['A1']=$A1;
//本当は$A1はあらかじめ求められて,ファイルなどに保存されている。
$pagetoshow=0; //0:loginページを表示,1:メニューメージ(セッション開始),999:logout作業 2以降は必要に応じて定義
$message="";
session_save_path("./");/*セッション保存用のファイルのパスの設定 本当はもっと安全なところに設定する*/
if (isset($_POST['login']) && isset($_POST['userID']) && isset($_POST['userPASS']) && isset($_POST['realm']) && isset($_POST['nonce'])) { //ログインボタンが押された
//$_POST['userPASS']はA1ダイジェストされた文字列が来る
$message .= "login要求受け付けました。 ";
$strcheck=TRUE;
session_start();
if (isset($_SESSION["mynonce"])) {
$mynonce=$_SESSION["mynonce"];
session_destroy(); //ログイン用セッションの終了
} else {
$strcheck=FALSE;
$message .= "認証できません。(セッションが継続していません)";
$pagetoshow = -1;
}
if (!preg_match('/\A([0-9A-Fa-f])+\Z/',$_POST['userPASS'])) $strcheck=FALSE;
if (!preg_match('/\A([0-9A-Za-z_ ])+\Z/',$_POST['realm'])) $strcheck=FALSE;
if (!preg_match('/\A([0-9A-Fa-f])+\Z/',$_POST['nonce'])) $strcheck=FALSE;
$userID = htmlspecialchars($_POST['userID'], ENT_QUOTES);
if (!preg_match('/\A([0-9A-Za-z_ ])+\Z/',$userID)) $strcheck=FALSE;
if ($strcheck===TRUE) {
$A1=getPASSWD_A1($userID);
if ($A1!==FALSE) {
$A2= hash('sha256', $mynonce . ":" . $A1); //$message .= $A2 . " ";
//$A2= hash('sha256', $_POST['nonce'] . ":" . $A1); $message .= $A2 . " ";
if ($_POST['userPASS']===$A2) { //認証された
$message .= $userID . "さん 認証に成功しました。";
$pagetoshow = 1;
$_SESSION = array();
session_id(hash('sha256',uniqid(rand(), 1))); // セッションID更新
session_start();
//セッションを作成する
$_SESSION["userID"] = $userID; //サーバに値を保存
$date = date('c');
$message .= 'セッションをオープンしました。';
} else {
$message .= $userID . "さん 認証に失敗しました。";
$pagetoshow = -1;
}
} else {
$message .= $userID . "さんは未登録のユーザです";
$pagetoshow = -1;
}
} else {
$message .= "認証できません。(リクエスト異常)";
$pagetoshow = -1;
}
} else if (isset($_POST['menupage']) && isset($_COOKIE[session_name()]) ) { //選択ボタンが押された
session_start();
if (isset($_SESSION["userID"])) {
$userID = $_SESSION["userID"];
$pagetoshow=1;
} else {
$pagetoshow=-1;
$message .= "継続できません。(セッション異常)";
}
} else if (isset($_POST['work1']) && isset($_COOKIE[session_name()]) ) { //作業1ボタンが押された
session_start();
if (isset($_SESSION["userID"])) {
$userID = $_SESSION["userID"];
$pagetoshow=101;
} else {
$pagetoshow=-1;
$message .= "継続できません。(セッション異常)";
}
} else if (isset($_POST['work2']) && isset($_COOKIE[session_name()]) ) { //作業2ボタンが押された
session_start();
if (isset($_SESSION["userID"])) {
$userID = $_SESSION["userID"];
$pagetoshow=201;
} else {
$pagetoshow=-1;
$message .= "継続できません。(セッション異常)";
}
} else if (isset($_POST['work3']) && isset($_COOKIE[session_name()]) ) { //作業3ボタンが押された
session_start();
if (isset($_SESSION["userID"])) {
$userID = $_SESSION["userID"];
$pagetoshow=301;
} else {
$pagetoshow=-1;
$message .= "継続できません。(セッション異常)";
}
} else if (isset($_POST['logout'])) { //ログアウトボタンが押された
session_start();
//既存のセッションを使用可能にする
$pagetoshow=999;
if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), '', time() - 1800, '/');
} // cookieの削除
session_destroy(); //セッションの終了
$message .= 'ログアウトしました。';
} else {
//初回は必ずここを通過する
$pagetoshow=0;
$message="ユーザの認証をします。";
session_start();
//認証用セッションを作成する
$nonce=MD5(uniqid(rand(), 1));
$_SESSION["mynonce"] = $nonce; //サーバに値を保存
//$message .= $nonce;
}
?>
<html>
<head>
<script src="./sha256.js"></script>
<script type="text/javascript">
<!--
function SubmitIdPass() {
var tmp1=document.frm_login.userID.value
+":"+document.frm_login.realm.value
+":"+document.frm_login.userPASS.value;
var shaObj1=new jsSHA(tmp1, "ASCII");
var sha256digest1 = shaObj1.getHash("SHA-256", "HEX");
var tmp2=document.frm_login.nonce.value+":"+sha256digest1;
var shaObj2=new jsSHA(tmp2, "ASCII");
var sha256digest2 = shaObj2.getHash("SHA-256", "HEX");
document.frm_login.userPASS.value=sha256digest2;
document.frm_login.submit();
}
// -->
</script>
</head>
<body>
<h1>sha256 sessionテスト</h1>
<?php if ($pagetoshow==-1) { ?>
<?php print $message ."<br><br>"; ?>
<form method="post">
<input type="submit" name="again" value="やり直し"><br>
</form>
<?php } else if ($pagetoshow==0) { ?>
<?php print $message; ?>
<p>
あなたのユーザIDとパスワードを入力して,ログインボタンを押してください。<br><br>
</p>
<form name="frm_login" method="post">
ユーザID <input type="text" name="userID"><br>
パスワード <input type="password" name="userPASS"><br>
<input type="hidden" name="realm" value="<?php echo $realm; ?>">
<input type="hidden" name="nonce" value="<?php echo $nonce; ?>">
<input type="hidden" name="login" value="">
<input type="button" onclick="SubmitIdPass();" name="" value="ログイン" >
</form>
<?php } else if ($pagetoshow==1) { ?>
<?php
print "こんにちは,<b>" . $userID . "</b>さん。<br>\n";
print $message;
?>
<p>
作業を選択してください。<br>
<form method="post">
<input type="submit" name="work1" value="作業1"> 作業1を行います。<br>
</form>
<form method="post">
<input type="submit" name="work2" value="作業2"> 作業2を行います。<br>
</form>
<form method="post">
<input type="submit" name="work3" value="作業3"> 作業3を行います。<br>
</form>
<form method="post">
<input type="submit" name="logout" value="ログアウト"><br>
</form>
<?php } else if ($pagetoshow==101) { ?>
<?php
print "こんにちは,<b>" . $userID . "</b>さん。<br>\n";
print $message;
?>
<p>作業1<br> :<br> :<br></p>
<form method="post">
<input type="submit" name="menupage" value="作業選択">
</form>
<form method="post">
<input type="submit" name="logout" value="ログアウト"><br>
</form>
<?php } else if ($pagetoshow==201) { ?>
<?php
print "こんにちは,<b>" . $userID . "</b>さん。<br>\n";
print $message;
?>
<p>作業2<br> :<br> :<br></p>
<form method="post">
<input type="submit" name="menupage" value="作業選択">
</form>
<form method="post">
<input type="submit" name="logout" value="ログアウト"><br>
</form>
<?php } else if ($pagetoshow==301) { ?>
<?php
print "こんにちは,<b>" . $userID . "</b>さん。<br>\n";
print $message;
?>
<p>作業3<br> :<br> :<br></p>
<form method="post">
<input type="submit" name="menupage" value="作業選択">
</form>
<form method="post">
<input type="submit" name="logout" value="ログアウト"><br>
</form>
<?php } else if ($pagetoshow==999) { ?>
<p>
ログアウトしました。<br>
</p>
<?php } ?>
</body>
</html>