/**
 * beatSession: File session handler
 *
 * @package   beat/session
 * @version   Bata release 1.4 (2010-04-23)
 * @link      http://www.sound-uz.jp/php/
 * @author    Yuji Iwashita <php@sound-uz.jp>
 * @copyright Yuji Iwashita
 */

【・・・このドキュメントは書きかけです】


【概要】

セッションハイジャックの可能性をぐっと低くするセッションハンドラです。

クライアント固有の値を埋め込んだ独自の長~いセッションIDを用いて
そのクライアントが生成しうるIDか検証した上でセッションを復帰します。
万一盗まれたIDが用いられても、セッションを復帰することは困難です。

クライアントに渡すセッションIDとストレージ側(サーバーの記憶媒体側)に渡すIDが異なるため、
セッションIDを使ってセッションのファイルに直接アクセスことはできません。

また、PHPデフォルトでは、外部から与えたセッションIDによって
古いセッションファイルが再び復帰されてしまいますが、
beatSession では、有効期限切れのファイルは復帰されず、新しいセッションが生成されます。
セッションIDを更新した場合、古いセッションファイルはその時点で削除されます。

このように、PHPデフォルトのセッションよりも、少しセキュリティがアップした仕様になってます。


尚、セッションIDを独自に実装にしているため、
セッションIDの生成に影響する関数は使えません。

 × session_start() 
    この代わりに、beatSession::start() にてセッションをスタートします。

 × session_regenerate_id()
    この代わりに、beatSession::start() に true を指定してセッションをスタートします。

 △ session_id()
    セッションIDを取得するには問題ありませんが、設定することはできません。


この他の関数は問題なく使えます。
またSIDの付与などセッションの挙動は、全てPHPの設定に依存します。




【適用】

PHP4.3以降を対象で書いていますが PHP5.2でもテスト済みです。

残念ながら、モバイル端末などのIPがコロコロ変わるクライアントには使えません。
(今後の課題とします。)


物理的に同じサーバー(http と https 間、サブドメイン違いなど)なら
次の条件を満たせば、セッションIDをURL渡しするだけでセッションが引き継がれます。

 1.物理的に同じコンピュータで session.save_path が同じ場合など、
   セッションの保存先が共有できること。

 2.コンストラクタの引数 $genKey, $serverKey が、http と https とも同じであること。

   $genKey は管理者固有のユニークな任意の文字列、
   $serverKey はサーバー固有のユニークな任意の文字列です。

   省略した場合はどちらも自動的に値が振られますが、推測できない値ではないので
   管理者にしかわからない推測されにくい任意の文字列を設定することをおすすめします。

      これらが同じであれば、beatSession は同じサーバーとみなして
      セッションIDの生成と検証をおこなうので、結果、異なるドメインや 
      http と https 間でセッションを共有出来ます。




【更新履歴】

2010-04-21 Bata release 1.4

 PHPデフォルトの仕様に近づけるため、
 IPアドレスによる検証をオプションに変更。デフォルトでOFFです。
 
 これに伴ないコンストラクタに第3引数を追加。

 あわせてこの設定を変更する setValidateIp() を追加。


2010-04-21 Bata release 1.3

 タイムスタンプをベースに生成される文字列を可変長に変更。


2010-04-20 Bata release 1.2

 セッションを全て破棄する beatSession::remove() を追加。
 session_destroy() はセッションデータの破棄だけが行われますが
 これに加え$_SESSION変数とCookieの破棄も一緒に行います。


2010-04-18 Bata release 1.1

  セッションIDの生成を、対クライアント側と対ストレージ側で
  異なる方法に変更。これにより、クライアント側IDからストレージ側IDの
  推測を困難にします。

 セッションの保存にファイル以外のストレージを実装するための
 メソッド _sessionExists() と、_sessionAlive() を追加。
 open()、read()、write()、close()、destroy()、gc() に加え
 前記2つのメソッドをオーバーライドすることで、異なるストレージ用の
 セッションハンドラの作成を容易にします。


2010-04-05 Bata release 1.0



【ファイル構成】

session.php	- beatSession クラス本体



【簡単な使い方】

<?php
/**
 * 1.セッションの設定
 *
 * PHPのセッションの設定値をそのまま用います。
 * 設定は必ずセッションスタート前に済ませておくこと。
 * この辺はPHPのセッションと変わりません。
 */
ini_set('session.save_path', '/home/userdir/sesstmp');
ini_set('session.gc_maxlifetime', '1800');


/**
 * 2.クラスのロード
 */
require_once '/home/userdir/lib/beat/session.php';


/**
 * 3.インスタンス生成
 */
$Sess = new beatSession();


/**
 * 4.セッションスタート
 *
 * セッションハンドラの登録(session_set_save_handler)と
 * セッションスタート(sesssion_start)をおこないます。
 *
 * 直接 session_start() をコールせず、必ず beatSession::start() で
 * セッションをスタートしてください。
 *
 * また、session_regenerate_id() はセッションIDの整合性が崩れるので、
 * セッションIDを変えたい時は、beatSession::start() の引数に true を指定してください。
 *
 * $Sess->start(true);
 * 
 */
$Sess->start();


/**
 *
 * これ以降は、スーパーグローバル変数 $_SESSION を介して値の入出力が行えます。
 *
 */



【ファイルストレージ以外のセッションハンドラ】

Mysqlしか使ってないので Mysql用のセッションハンドラだけは書きました。
この他のストレージ用のセッションハンドラは、beat/session/mysql.php を
参考に実装してみてください。

基本的には、beatSession を継承したサブクラスで
open()、read()、write()、close()、destroy()、gc() に加え、
_sessionExists() と、_sessionAlive() の計8つのメンバー関数をオーバーライドします。

_sessionExists($id) は、$idで指定されるセッションが
ストレージに存在するか確認し、bool で結果を返すよう実装します。
true: 存在する / false: 存在しない

_sessionAlive($id, $maxlifetime) は、
$idで指定されるセッションの最終更新時刻(タイムスタンプ)が
$maxlifetime で指定される生存時間(秒数)を過ぎていないか
有効期限を確認し bool で結果を返すよう実装します。
このため、ストレージには最終更新時刻を保存できるフィールドが、
write() では最終更新時刻を保存するよう実装することが必須です。

(セッションの最終更新時刻) > (現在時刻 - $maxlifetime)

この式が成立すれば、true: 有効期限内 / false: 有効期限切れ


また、beatSession は、クライアント側とストレージ側で異なるIDを使用します。
ハンドラ関数が受け取る引数 $id は、セッションIDではなくストレージIDです。
セッションハンドラの実装では session_id() で得られるセッションIDではなく
必ず引数で与えられたストレージIDを用いてください。

また、PHPデフォルトではセッションIDに32文字の16進数文字列が用いられていますが
beatSession のストレージIDは 40文字の16進数文字列ですので
保存するバイト数にはご注意ください。



Icon  Name                    Last modified      Size  Description
[DIR] Parent Directory - [TXT] mysql.php 13-Feb-2011 03:58 4.1K [TXT] readme.txt 13-Feb-2011 03:58 8.1K