phpのsessionとcookieについて
質問は以下に2つです。
プログラムの説明は、pass,idから認証を行い、sessionidを発行します。二度目の以降はsessioidから認証します。
sidpost.phpからpostでIDとパスワードを入力させます。
データベースはid, pass, sidの3つのカラムがあります。
<?PHP
require_once'DB.php';
session_name("sid");
session_start();
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<?php
$id = $_POST['id'];
$pass =$_POST['pass'];
$cookie = $_COOKIE['sid'];
$sid = session_id();
//データベース参照
//プレースホルダーを使用
//id からpassを参照する
//cookie から sidを参照する
$data=$sth->fetchRow(DB_FETCHMODE_ASSOC);//参照したデータを$dataの連想配列に格納
//sid保存のプレースホルダー
$sth2 = $dbh->prepare('UPDATE accountid SET sid=? WHERE id=? AND pass=?');
//cookieが保存されていない場合
if(!isset($cookie) && isset($pass) && isset($id)){
//idとpassから認証
if($pass === $data['pass']){
$sth2 = $dbh->execute($sth2, array($sid, $id, $pass));
echo "初めてのログインsid登録";
}
//sidがある場合cookieとデータベースのsidを比較
}else if(isset($cookie)){
if($cookie == $data['sid'])
echo "sidあり成功";
//クッキーがあり、データベースと一致しない場合,sidを破棄する
}else{
echo"あるはずのクッキー" .$COOKIE['sid']."<br>";
$_SESSION=array();
setcookie('sid', '', time()-3600);
session_destroy();
echo "ないはずのクックキー".$_COOKIE['sid'];
}
//それ以外は入力フォームにリダイレクト
}else{
header("location: ./sidpost.php?error=error");
}
$dbh->disconnect();
?>
</body>
</html>
上のようなセッション管理のプログラムを書きました。
質問は2つありまして、
・1つめは、通常セッション管理を行う際の、条件はどのようにするのが一般的ですか?
IDとパスワードがデータベースと一致する場合としない場合の2通り、cookieがある場合、ない場合の2通り、もしcookieがある場合は、データベースの値と一致する場合としない場合の2通りが考えられます。一番最適な条件文はどのようにすればよいでしょうか?
またその処理はどのようにすればよいのでしょうか。
例えばcookieがあり、データベースと一致しない場合、$_SESSIONの初期化、setcookieでクッキーの削除、session_destroy()するなど。。。なにかよくわからなくなってしまいました。
・二つ目は、
上のプログラムではじめsession_name('sid')およびsession_start()を宣言し、クライアントとサーバに$sid=session_idを発行しています。なので、$_COOKIE['sid'];の値には
session_id()($sid)になっているはずです。
下のほうで、セッションの管理を行う際、
//クッキーがある場合
else if(isset($cookie)){
if($cookie == $data['sid'])
echo "sidあり成功";
//クッキーがあり、データベースと一致しない場合,sidを破棄する
}else{
echo"あるはずのクッキー" .$COOKIE['sid']."<br>";
$_SESSION=array();
setcookie('sid', '', time()-3600);
session_destroy();
echo "ないはずのクックキー".$_COOKIE['sid'];
}
クッキーがあり、データベースと一致しない場合に、sessionおよび、cookieの破棄をしています。この前後でechoをもちいて$_COOKIE['sid']の値を出力すると、
破棄するの前のechoでクッキーが表示されず、
破棄したあとのechoでクッキーが表示されました。
なぜこのような結果になるのですか、逆では?と思いました。
お礼
早速のご回答ありがとうございます。 まず、質問返しになってしまい申し訳ないのですが、セッションIDを発行してクライアントを個人として認識できるということはわかります。 クライアントというか、「その通信」って事ですよね。 セッションIDがあれば「その通信」だとサーバーから見分けられる。 そして変数名は同じでも通信毎にプライマリな扱いになるのはセッションIDがあるからである。 うん、納得です。 >つまり両方ともクライアント側にデータがありますが、、、 ここが。。なんとも。 あっセッションIDのみクライアント側で保存する。 そういう事か! なるほど! クッキーにセッションIDを持たせて、そのIDで、、 なるほどです。そのIDでリクエストがあれば、サーバー側で認識できる。 そのIDにひもづく細かいデータはサーバー側に記憶される。 だから、セッションに格納しすぎるとサーバー付加が上がる。 なるほど。理解できました!(あってるのかな。。) あとは、おっしゃるとおりパフォーマンスなどとは別に 「セキュリティ」という角度で考えたときに 問題のあるものはセッション。 問題ないものは、クッキーにあずけちゃう。 そういう事ですよね! ありがとうございます! セキュリティ>ユーザービリティの優先順位で格納する場所の判断基準ができました。 自分の実装に確固たる理由があるというのはいいものです。 すっきりします。 丁寧な解説ありがとうございましたmm