【PHP】なぜかセッションが切れる問題の犯人は、session_regenerate_id(true)だった

プログラミング

どうも、コウイチです。

 

PHPでログイン機能を作っているのですが、セッション変数が勝手に削除されてしまうバグが発生して困っていました。

なんとか解決しましたので、ここに記したいと思います。

強制的にセッションが消えるバグが発生

強制的にセッションが消えるバグです。

具体的には、ログイン後の各画面で最初にセッション変数をチェックし、ログインしていたら表示し、ログインしていなければ強制終了するようにしています。

 

しかし、各画面間の移動で頻繁に、ログインされていない処理の方が走ってしまい、強制終了してしまうのです。

 

大事なデータを送信中に、強制終了にでもしたら大変。

その膨大なデータの入力時間が無駄になります汗

 

こんなシステム、誰も使いたくない。。。

 

というわけで、この致命的なバグを解決すべく、ググりまくりました。

 

するとある関数が原因だと判明し、めでたく解決に至りました\(^o^)/

 

というわけで、その解決方法を見ていきましょう。

session_regenerate_id(true)が悪さをしていた!?

PHPでログイン機能を実装している場合、セッション管理には、session_start()とともに、session_regenerate_id(true)を使用していると思います。

 

<?php
session_start(); // セッションの開始
session_regenerate_id(true); // セッションIDの振りなおし

 

どうやらこれが悪さをしているというのです。

 

session_regenerate_id(true)とは

PHP公式関数リファレンスより

session_regenerate_id 現在のセッションIDを新しく生成したものと置き換える

 

セッションID固定化攻撃の対策として、ログイン認証直後や、ログイン後の各画面の先頭にて、セッションIDを新しく振りなおすことで、攻撃を防ぎます。

 

が、この関数、短い間隔で呼び出されると、処理が追い付かずに、仕舞にはセッションが消えてしまうようなのです。

 

例えば、ログイン中の画面で

  • 画面遷移のリンクをダブルクリックする。
  • 画面遷移のリンクをクリックして、間髪入れずにまた別のリンクをクリックする。

などの行為を行うと、各ページの先頭に書かれたsession_regenerate_id(true)を短い間隔で実行させることになってしまい、セッションが消えてしまうことがあるのです。

 

必ず消えるわけではありませんが、消えたり消えなかったり、かなり不安定です(サーバーにもよります)。

 

僕の環境では、ローカル環境(XAMPP)で作業していた時には問題は起きませんでしたが、本番環境のサーバーにアップした途端、この事象が発生しました。

結論

調べた末、session_regenerate_id(true) を呼び出すのはログイン認証を行った直後のみとしました。

 

これはセッションハイジャックの話が絡んできて、サイトの処理内容にもよるのですが、

ログイン後にsession_regenerate_id()を実行するだけで十分か? にあるように、必ずしも安全であるわけではないです。

 

自分のサイトは安全か?を考えてみてください。

 

ただ、サイトを利用するユーザーとしては、入力中のデータが飛ぶ可能性のある、かなり致命的なバグになりますので、

なんか時々セッション切れるな?

と感じたら、早急に対策することをオススメします。

 

ではまた。

コメント