結論
ファビコン(favicon.ico)は正しく設定しよう!
ファビコンが正しくないからセッションが消える、というのは全く思いつかないことでした。
まあ、正確に表現すると、ファビコンを正しく設定していなかったために、セッションの一部データが上書きされたということなのですが。
経緯
あるシステムの管理画面を作成しており、その中で管理者のパスワード変更機能をテストしていました。
管理者の一覧がテーブルで表示されており、行ごと(管理者ごと)にパスワード変更ボタンがあります。パスワード変更ボタンを押すと、
https://*/admin/edit_pass/1
のようなURLへと遷移します。
URL末尾の「1」がパスワード変更対象の管理者IDになります。
PHPのフレームワークにはCodeIgniterを使用しているので、実際のコードは
public function edit_pass($id)
といった関数になり、末尾の「1」はパラメータ$idに入るわけです。
edit_pass関数では、まず$idの管理者IDが存在していることを確認するため、$idをキーにして、管理者を検索します。管理者の存在が確認できれば、セッションに管理者の情報を配列で、セッションに保存します。
それから、パスワード変更用のビューをロードして、ブラウザで表示します。
ブラウザから新しいパスワードがポストされると、セッションから管理者情報を読み取り、その管理者のIDを使用してDBの情報を書き換えます。
これらの処理は特に難しいこともなく、何度も繰り返し書いてきたよくあるコードです。
ところが、フォームから新しいパスワードをポストした後、DBのテーブルを更新する処理が実行されませんでした。ログを取って調べてみると、セッションから管理者情報を読み込めなかったために、更新処理を行っていないのでした。
原因
セッションに入れたはずの管理者情報が消えていたのは、edit_pass関数が2回実行されていたためでした。
1回目は、$idパラメータに管理者ID「1」が正しく設定されていました。これにより、DBから管理者情報を正しく取得でき、セッションにも管理者情報が書き込まれていました。
2回目は、$idに「favicon.ico」という文字列が入っていました。このため、DBから管理者情報を取得できず、セッションには空のデータが上書きされていたのでした。
HTMLのヘッダーで
<link rel="shortcut icon" href="favicon.ico">
と設定していたために、ファビコンを読み込もうとして
https://******/edit_pass/favicon.ico
にアクセスしていたと考えられます。このため、$idパラメータにfavicon.icoが入ってしまったのでした。
対策
ファビコンのパスを正しく設定しました。
<link rel="shortcut icon" href="<?=base_url('favicon.ico')?>">
base_urlというのはCodeIgniterで使用できる関数で、サイトのベースのURLを返してくれます。この場合、
https://*****/favicon.ico
というURLになります。
たったこれだけのことでしたが、分かるまでに結構時間を費やしてしまいました(ローカルサーバーのPHPを 7.1→7.3 にバージョンアップまでしました)。
で、結論。
ファビコン(favicon.ico)は正しく設定しよう!
となるわけです。