web-dev-qa-db-ja.com

ajaxを使用してログアウトを強制すると、dbテーブルが更新されない

タイトルにあるように、dbテーブル_trace_users_は更新されませんアクティビティが30分間発生しない場合ですが、6分になると更新されます。

次のコード(JSとPHPの両方)は、同じphpファイルmno.php内にあります。

以下のスクリプトにあるこの行let lastActivity = <?php echo time(); ?> ;を介して、ユーザーの最後のアクティビティを保存しています。

_<?php
session_start();     
if (isset($_GET['action']) && $_GET['action'] == "logout")
{
    session_destroy(); // destroy session data in storage
    !isset($_SESSION['pageadmin']);
    $open = "false";
    $write = "0";
    $stmt = $connect->prepare("UPDATE trace_users SET open=?, write=? WHERE user_name=?");
    $usname = !empty($_SESSION['user_name']) ? $_SESSION['user_name'] : '';
    $stmt->bind_param('sss', $open, $write, $usname);
    $stmt->execute();
}
?>
<script>
    jQuery(document).ready(function($) {

        let lastActivity = <?php echo time(); ?> ;  // storing last activity of user

        let now = <?php echo time(); ?> ;

        let logoutAfter = 360;

        let timer = setInterval(function() {
            now++;
            let delta = now - lastActivity;
            console.log(delta);
            if (delta > logoutAfter) {
                clearInterval(timer);
                //DO AJAX REQUEST TO close.php
                $.ajax({
                    url: "/abc/mno.php",
                    type: 'GET',
                    data: {
                        action: 'logout'
                    }, // Line A
                    success: function(data) {
                        console.log(data); // Line B
                    },
                    error: function(jqXHR, textStatus, errorThrown) {
                        alert(textStatus);
                    }
                });
            }
        }, 1000);
    }); 
</script>
_

問題ステートメント:

分間(1800秒)アクティビティが発生しない場合、dbテーブルも更新される必要がありますとなるように、上記のコードでどのような変更を行う必要があるのか​​と思います。

Case1(機能していない):1800秒(ページがログアウトしますdbは更新されません
Case2(作業中):60秒(ページがログアウトしますdbが更新されます

Session.gc_maxlifetime内の値は1440(ローカル値)1440(マスター値)です。

これは私が試した/デバッグしたものです:

ネットワークタブで、リクエストメソッド[〜#〜] get [〜#〜]セッションタイムアウトが設定されている場合6分および60分

3
user1950349

PHPプロセスは無期限に存在せず、Node.jsサーバーのループとしてプログラム構造を備えていません。これは、プロセスを無効にするプロセスではなく、セッションに関連付けられた単純なタイムスタンプであるため、セッションの期限切れに対応できません。を使用しようとするたびにチェックされます。

私が提供するソリューションは、N分ごとに実行される単純なスクリプトで、最後のユーザーアクティビティのタイムスタンプ(そのユーザーのリクエストで更新されると想定しています)と有効期限(あなたの場合は30分です)を比較します。必須ではありませんが、セッションの有効期限を30分に設定することもできます。時差が30分を超える場合は、テーブル内のユーザーのタイムスタンプを更新し、必要に応じてセッションを無効にします。スクリプトはcronまたはその代替手段を介して実行でき、チェックの実行に必要なすべてのユーザーを通過できます。

ユーザーがサーバーにログアウトしているが、クライアントはそれを認識しておらず、ログアウト要求を送信し続ける可能性がある場合のケースを処理することを忘れないでください-警告ボックスの発生はかなり不明確です(HTTP Unauthorizedコードを返して別の方法で処理することをお勧めします-リダイレクトログイン画面など)

1

問題は、N秒後にセッションの有効期限が切れるのを妨げるような変更は行わず、この時間後にセッションを破棄するようにスクリプトをコーディングしていることです。セッションgc(ガベージコレクター)は定期的に実行され、古いセッションを削除します。その場合、$_SESSION['LAST_ACTIVITY']も削除されます。

GCがセッションを削除しないようにするか、アプリケーションのロジックを変更する必要があります。

1
Enrico Dias

修正する必要のあるものが2つあります。

1)。 ajaxリクエストをasync:falseに設定します。

$.ajax({
    url: "/abc/mno.php",
      type: 'GET',
      async: false,   //  <---- ADDED ASYNC FALSE
      data: {
        action: 'logout'
    }, // Line A
     success: function(data) {
        console.log(data); // Line B
      },
     error: function(jqXHR, textStatus, errorThrown) {
         alert(textStatus);
       }
 });

2)。 SQLクエリを実行した後、セッションを破棄します。

<?php
session_start();     
if (isset($_GET['action']) && $_GET['action'] == "logout")
{
    !isset($_SESSION['pageadmin']);
    $open = "false";
    $write = "0";
    $stmt = $connect->prepare("UPDATE trace_users SET open=?, write=? WHERE user_name=?");
    $usname = !empty($_SESSION['user_name']) ? $_SESSION['user_name'] : '';
    $stmt->bind_param('sss', $open, $write, $usname);
    $stmt->execute();
    session_destroy(); // destroy session data in storage <---- DESTORY AT THE END
}
?>
0
Hackinet