3

興味深い問題に出くわしました。私が取り組んでいるサイトには、現在、login.php、welcome.php、ajax.php の 3 つのページがあります。それらはすべて、コードの先頭で session_start() を呼び出します。Login.php は $_SESSION[] 変数をチェックして、誰かがログインしているかどうかを確認します。そうでない場合は、name/pwd を取得し、ajax.php に連絡して name/pwd を確認し、適切な $_SESSION[] 変数を設定してログインします。Welcome.php は適切な $_SESSION[] 変数を探し、ユーザーにウェルカム メッセージを表示します。設定されていない場合は、ユーザーにログインを求めます。典型的な動作であり、典型的な方法で使用すると完全に機能します。

ただし、login.php とwelcome.php を一連のタブとしてブックマークし (Firefox などで)、両方を同時に開くと、奇妙なことが起こります。おそらく、session_start() がまったく同時に 2 回呼び出されるため (error_log() を使用してチェック)、2 つの別個のセッションが作成されます (session_id() でチェック)。session_start() がたまたま「最後」に呼び出された場合 (タイムスタンプは同じですが) は、残っているセッションです。これは、次のシナリオで問題を引き起こします: login.php の session_start() が、welcome.php の session_start() が呼び出される前に呼び出されます。

この場合、login.php で作成されたセッションは、更新されない限りそのページに存在し続けます。ただし、名前/パスワードの詳細を確認するために ajax.php に接続し、ajax.php が session_start() を呼び出すと、welcome.php によって作成されたセッションが取得されます。不合格。そのため、login.php が最初に session_start() を呼び出す場合、welcome.php の session_start() が新しいセッションを作成しないようにする方法を考え出す必要があります。注: 呼び出し順序は一貫しておらず、login.php の session_start() が最後に呼び出されている限り (これは制御できません)、明らかにすべて正常に機能します。

理想的には、2 番目のファイルが最初のファイルがsession を作成中であることを認識する何らかの方法があるため、独自のファイルを作成しないでください (ただし、welcome.php の場合のみ)。

これは他の人が対処した問題であるに違いありませんが、私はこれらのここのインターウェブでそれについての言及を完全に見つけることができませんでした. どんな助けでも大歓迎です。

EDIT1: 問題を再現するために必要なファイルは次のとおりです。

ログイン.PHP

<?php
session_start();
error_log("login.php, session id: ".session_id());
$_SESSION['user'] = "EleventyOne"
?>
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>multiple session bug - login</title>

<script src='jquery-1.9.1.js'></script>
<script>

    $(document).ready(function() {
        $.ajax({
                url : 'ajax.php',
                data : { 'func' : 'check_login' },
                dataType : 'json',
                type : 'GET',
                timeout : 10000
            })
        .done(function(data,textStatus,jqXHR){
            alert("Done: "+data.status);
        })
        .fail(function(jqXHR,textStatus,errorThrown) {                    
            alert("Failed: " + textStatus + "(" + errorThrown + ")");
        });
    }); // end ready

</script>
</head>

<body>
</body>
</html>

ようこそ.PHP:

<?php
session_start();
error_log("welcome.php, session id: ".session_id());
$message = "";

if ( isset($_SESSION['user']) ) {
    $message = "Hello, ".$_SESSION['user'];
}
else {
    $message = "Please login!";
}
?>

<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>multiple session bug - welcome</title>
</head>

<body>
<div>
<?php echo $message; ?>
</div>
</body>
</html>

AJAX.PHP:

<?php
session_start();
error_log("ajax.php, session id: ".session_id());

// ignoring $_GET[] here, as superfluous to the point...

if ( isset($_SESSION['user']) ) {

    // check the database for that user...
    // ...

    // return status
    $ret['status'] = "ok";
    echo json_encode($ret);
    exit;
}
else {
    // return failed status
    $ret['status'] = "broken session";
    echo json_encode($ret);
    exit;
}
?>

<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>multiple session bug - ajax</title>

<script src='_js/jquery-1.9.1.js'></script>
<script>

    $(document).ready(function() {
    }); // end ready

</script>
</head>

<body>
</body>
</html>

login.php をロードし、新しいタブを開き、welcome.php をロードすると、取得される error_log ファイルは次のとおりです (すべて問題ありません)。

[27-Jun-2013 18:39:40 UTC] login.php, session id: skofpr8g0tg81aqohnkahv3vk5
[27-Jun-2013 18:39:40 UTC] ajax.php, session id: skofpr8g0tg81aqohnkahv3vk5
[27-Jun-2013 18:39:44 UTC] welcome.php, session id: skofpr8g0tg81aqohnkahv3vk5

login.php とwelcome.php を一連のタブとしてブックマークし、ブラウザーを閉じてから再度開き、両方のタブを同時に開くと、どちらの session_start が最初に呼び出されたかに応じて、2 つの error_log ファイルのいずれかが取得されます。 .

これは、login.php の session_start() が ajax.php に対して持続するため、機能します。したがって、ajax.php は「ok」のステータスを報告します。

[27-Jun-2013 18:40:39 UTC] welcome.php, session id: 6q2q96lhhoaqqhj214gs3gos36
[27-Jun-2013 18:40:39 UTC] login.php, session id: j8eaa5mtfsla9q3q80qt03kvt7
[27-Jun-2013 18:40:39 UTC] ajax.php, session id: j8eaa5mtfsla9q3q80qt03kvt7

これは、welcome.php の session_start() が ajax.php に対して存続するため、機能しません。

[27-Jun-2013 18:40:18 UTC] login.php, session id: s4b7jo41jpg1ubbe8at7c5qr35
[27-Jun-2013 18:40:18 UTC] welcome.php, session id: freu86sn3edc3fuoc2pn875o90
[27-Jun-2013 18:40:18 UTC] ajax.php, session id: freu86sn3edc3fuoc2pn875o90
4

2 に答える 2

1

私が思いついた最善の解決策は、セッションの「作成」(つまり、セッション変数の設定) を ajax.php ファイルに移動することでした。このファイルは、ユーザーが uname/pwd を正常に送信した後にのみ実行され、リダイレクトされようとしています。いずれにせよ、新しいページ (つまり、welcome.php) に移動します。これは、login.php が ajax.php によって設定されたセッション変数にアクセスできることを保証できないことを意味します。そのため、何が起こっているかを知るために ajax 呼び出しのみに依存している単なる愚かなページです。結局のところ、これはそれほど面倒なことではありません。

于 2013-08-11T01:18:35.983 に答える
0

もう一方を上書きする場合、一方のプロセスを疑います。一度に同じセッション ファイルを開くことができるプロセスは 1 つだけです。2 つ目 (およびそれ以降) は、セッション ファイルが使用可能になるのを待ってハングします。

私の経験からすると、 $_SESSION は見かけほど魔法のようなものではありません。ブラウザの Cookie などを使用して、ディスク上の同じファイルを毎回読み書きするようにしているだけです。以前は、必要なときにのみ session_start() を使用して、この問題を回避していました。つまり、すべてのページの先頭でセッションを開く代わりに、$_SESSION から情報を書き込んだり取得したりする直前に session_start を実行し、それが終わったらすぐに session_write_close を実行しました。

于 2013-06-27T18:06:09.867 に答える