1. ホーム
  2. php

[解決済み] PHPのセッションを30分後に失効させるにはどうしたらいいですか?

2022-03-16 16:33:16

質問

セッションを30分間保持し、その後破棄する必要があります。

どのように解決するのですか?

独自にセッションタイムアウトを実装する必要があります。他の人が言っているオプションはどちらも ( セッション.gc_maxlifetime セッション.cookie_lifetime ) は信頼できません。その理由を説明します。

まず

セッション.gc_maxlifetime
セッション.gc_maxlifetime は、データが「ゴミ」とみなされ、クリーンアップされるまでの秒数を指定します。ガベージコレクションはセッション開始時に行われます。

しかし、ガベージコレクタが起動するのは、確率的には セッション.gc_probability で割ったもの セッション.gc_divisor . そして、これらのオプションのデフォルト値(それぞれ1および100)を使用すると、確率は1%にしかなりません。

まあ、ガベージコレクタがより頻繁に起動するように、これらの値を調整すればいいだけなんですけどね。しかし、ガベージコレクタが起動すると、登録されたすべてのセッションの有効性をチェックすることになります。そして、それはコスト高になります。

さらに、PHPのデフォルトの セッション.save_handler ファイルで指定されたパスのファイルに、セッションデータが保存されます。 セッション.save_path . そのセッションハンドラでは、セッションデータの年齢は、最終アクセス日ではなく、ファイルの最終更新日で計算されます。

注意 デフォルトのファイルベースのセッションハンドラを使用する場合、ファイルシステムはアクセス時間(atime)を追跡する必要があります。Windows FAT はそうではないので、FAT ファイルシステムやその他のファイルシステムで atime を追跡できない場合は、セッションのガベージコレクションを処理する別の方法を考え出す必要があります。PHP 4.2.3 以降では、atime の代わりに mtime (更新日時) を使用するようになりました。そのため、atime 追跡が利用できないファイルシステムで問題が発生することはありません。

そのため、セッションデータファイルが削除されても、セッションデータが最近更新されていないため、セッション自体は有効であるとみなされることがあります。

そして2つ目。

セッション.クッキーの有効期限
セッションのクッキー有効期限 は、ブラウザに送信されるクッキーの有効期限を秒単位で指定します。[...]

はい、その通りです。これはクッキーの寿命に影響するだけで、セッションそのものはまだ有効かもしれません。しかし、セッションを無効にするのはサーバーの仕事であり、クライアントの仕事ではありません。ですから、これは何の役にも立ちません。実際 セッション.cookie_lifetime に設定します。 0 にすると、セッションのクッキーは本当の セッションクッキー ブラウザを閉じるまでしか有効でない。

結論/最善の解決策

最良の解決策は、独自のセッションタイムアウトを実装することです。最後の活動(つまりリクエスト)の時間を示す単純なタイムスタンプを使用し、リクエストごとにそれを更新します。

if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 1800)) {
    // last request was more than 30 minutes ago
    session_unset();     // unset $_SESSION variable for the run-time 
    session_destroy();   // destroy session data in storage
}
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp

リクエストごとにセッションデータを更新すると、セッションファイルの更新日も変更されるので、ガベージコレクタによってセッションが早々に削除されることはありません。

のようなセッションへの攻撃を避けるために、追加のタイムスタンプを使用して定期的にセッションIDを再生成することもできます。 セッションの固定化 :

if (!isset($_SESSION['CREATED'])) {
    $_SESSION['CREATED'] = time();
} else if (time() - $_SESSION['CREATED'] > 1800) {
    // session started more than 30 minutes ago
    session_regenerate_id(true);    // change session ID for the current session and invalidate old session ID
    $_SESSION['CREATED'] = time();  // update creation time
}

注意事項

  • session.gc_maxlifetime は、少なくともこのカスタム有効期限ハンドラの有効期限(この例では1800)と同じでなければなりません。
  • の30分後にセッションを失効させたい場合は、次のようにします。 活動 ではなく、30分後に 開始以来 を使用する必要があります。 setcookie の期限付きで time()+60*30 を使用して、セッションクッキーをアクティブに保つことができます。