PHP
PHPでセッションの内容が消えてしまう場合の対処

はじめに

PHPのセッションがうまくいかないことが合ってどっぱまり。。。why

セッションの情報が取得できていない!

調べていると、どうも途中でセッションの情報が取得できなくなっていた。色々と潰していくと、絶対起きる訳ではなく、発生するブラウザとそうでないものがある。

結論から行くと、4番目の理由だったのだけれども、一応その他でもセッションの取得がうまくいかなくなることがあるので記載しておこう。

  1. PHPのバージョンが古い
  2. session_regenerate_idを使用している
  3. destroyが中途半端
  4. SameSite Cookie 対応をしていない

PHPのバージョンが古い

PHP7.1以降でPHPでsession_start();が何らかの要因で失敗した際に空になってしまうの修正し、失敗しても以前の情報でアクセスを行うようになったようだ。なので、7.0以前を使用している場合は、空になってしまうことがある。

session_regenerate_idを使用している

セッションIDが盗まれないようにするために、アクセス毎にセッションIDを作り直す関数だが、連続したアクセスを行ったり、ネットワークの不調によってIDの書き換え失敗して、元のセッションにアクセスできなくなってしまうことがある。

仕様(バグ)のようで、そのままでは使用できない。一時的な対処方法もある(連続したアクセスを間隔を空けて処理する)ネットワークの不調などでもおきることから完璧ではない。IDを書き換えないことでの脆弱性はあるが、セッションIDが盗まれる状態だと意味がない(ブラウザのcookieを見ればわかってしまうため)

destroyが中途半端

cookieに保管されるセッションIDを見てサーバーのセッション情報を見に行くので、PHPSESSIDがクリア、もしくは書き換えら書き換えられなかったりするとなくなる。

SameSite Cookie 対応をしていない

大変恥ずかしながら、これがダメだった。特に設定していなかったのだけれども、GoogleChrome(80以降)だと、値がない場合に SameSite=Lax に設定される。で、これだけなら問題がおきないのだけれども、一度他のドメインに移動した後に元のサイトに戻ってきていた。クロスサイトしてしまうと、SameSiteのLaxではcookieが使えないので、セッションIDが取り出せない = サーバーの保管場所にアクセスできない、のでできなかった。

で、これが厄介なのは、じゃあ none の値(以前と同様の挙動)にすると、その他ブラウザで挙動がおかしくなることがあるので、他の対策をとったほうがいいとのこと。

  • useragentで処理を振り分ける
  • cookieを使用せず、独自の方法で情報を保存する
  • クロスサイトさせない

何れかで対応できる。自分は、useragentは元から排除した、というか、他のブラウザが対応し始めたときに処理内容を書き換えるのが面倒だったから。APIで処理できることだったので、三個目を採用。クロスサイトさせなければ問題ない。

cookie(またはsession)を使用せず、保存する情報が個人情報などが含まれないのであれば適当な場所にフォルダを作成し、ファイルに書き込んで、POSTかGETで他のドメインから戻ってくる際に情報を取得すればSamsiteは関係ないのでできる。