PHP – session_regenerate_id()でSessionが切れる

フレームワーク使用禁止でな、生PHPでSessionを扱ってsession_regenerate_id()でsessionIdをリクエスト毎に変更していたところSessionが切れる事があった。

確かに同時にsession_regenerate_id()が実行され、それがまさかのデータ引き継ぎ中だと、最終的に採用されるSessionの中身は空になってしまうわけだな。なのでsession_regenerate_id()を必ずしも同時に実行させないスクリプトがこんな感じになる。10分の1の確率で動作するので同時に2度リクエストされても、よっぽど同時実行されない。あんまり確率下げるとそもそもsession_regenerate_id()が実行されないなんてことにもなるからこの辺りは調整が必要だな。

<?php
session_start();
if(mt_rand(1, 10) === 1) {
session_regenerate_id(true);
}

このコードは以下を参考

scrap.php.xdomain.jp

ファイルでSessionを扱う場合はsess_から始まるファイルが生成されたりとかして、そのコストを削減したいって時は有効期限をつけるといい。参考にさせてもらったサイトのいくつかで有効期限チェックをやっていたので参考にしてみた。

<?php
session_start();
if (!array_key_exists('expires', $_SESSION)) {
$_SESSION['expires'] = time();
}
if(mt_rand(1, 10) === 1) {
if($_SESSION['expires'] < time() - 300) {
session_regenerate_id(true);
}
}

このコードは以下を参考

xirasaya.com

確かにリクエスト毎にファイル生成してるときついかな。でもセキュリティレベルを下げる事になるから、負荷が増えたらサーバーをスケールアップするか、Redisとか使ってSessionをメモリに乗せるとかしてスケールアウトしてもいいのかもなあ。。こういうのベンチマークとってみたいね。実は全体の負荷の大部分を占めてたりしてw

PHPの某フレームワークのコード読んでみたらユーザー認証時に一度だけSessionId変えているだけで常に変更していなかったりしてたけど、毎度変えるオプションが付いてるらしいので、どこで変えてるんだか。自前の処理でも作っているんだろうかね。

話それるけどフォームで画像認証をするときに、表示された画像内の文字列がSessionに入っている状態で別ページでsession_regenerate_id()が実行されると画像内文字列消えちゃうんじゃないかと一瞬思ったが、画像内文字列もちゃんと引き継がれるし、次のPOSTリクエスト時には新しいSessionIdでリクエストするんだから何も問題なかったな。少し混乱したw

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA