一部のセッション機能と、Chrome のプリフェッチ/レンダリングの方法に問題があります。フォーラム ソフトウェア (esoTalk) をカスタム laravel 4.3 アプリと接続しようとしています。フォーラムとアプリが認証の詳細を共有できるようにするphpセッション(組み込みのlaravelセッションに加えて)をlaravelに作成させる認証イベントリスナーがあります。フォーラムへのアクセス時に、ユーザーがログインしていなくても、この共有情報が存在する (ユーザーが laravel アプリにログインしている) 場合、フォーラムはセッションで利用可能な情報を使用してそのユーザーをログインさせます。
ほとんどの場合、これは正常に機能しますが、Chrome のプリフェッチが問題を引き起こしているようです。デバッガーを使用してフォーラムを監視すると、フォーラムの URL を入力すると、クロムを入力する前にフォーラムにアクセスできることがわかります。デバッガーを実行すると、必要なすべての処理が実行され、ログインに成功したことがわかります。最後のステップとして、フォーラムはセッション ID を再生成してハイジャックを停止します。これが壊れるところです。Chrome は新しいセッション ID (http SetCookie ヘッダー経由で送信) を無視するように見えるので、Enter キーを押すと、元のセッション ID を使用してフォーラムに移動します (そしてまったく新しい要求を行います)。この ID は存在しないため、新しい ID を設定すると、ログイン状態が失われます。ユーザーにとって、これはログインしていないように見えます。
これを回避する方法についての提案を求めて、高低をグーグルで検索しました。セッション ID の再生成を削除するのは、セキュリティ上の目的に役立つため、私は嫌です。また、クロムのプリフェッチ/レンダリングを無効にすることもできません。全体として、私は少しピクルスになっているようです。
これを再現するコードをいくつか作成しました。ただし、事前レンダリングの開始に依存しています (そのため、アドレス バーから各ファイルに何度もアクセスする必要があります)。
// test1.php
<?php
function regenerateToken()
{
session_regenerate_id(true);
$_SESSION["token"] = substr(md5(uniqid(rand())), 0, 13);
$_SESSION["userAgent"] = md5($_SERVER["HTTP_USER_AGENT"]);
}
// Start a session.
session_set_cookie_params(0, '/');
session_name("SessionBork_Test_session");
session_start();
$_SESSION["SentryUserId"] = '99';
regenerateToken();
header('Content-Type: text/plain');
foreach ($_SESSION as $k => $v) {
echo $k . " = " . $v . "\n";
}
test1.php に続いて test2.php にアクセスすると、一連のセッション変数の出力が表示されます。プリレンダリング/フェッチが開始されるとすぐに、壊れたメッセージが表示され始めます。
// test2.php
<?php
function regenerateToken()
{
session_regenerate_id(true);
$_SESSION["token"] = substr(md5(uniqid(rand())), 0, 13);
$_SESSION["userAgent"] = md5($_SERVER["HTTP_USER_AGENT"]);
}
// Start a session.
session_set_cookie_params(0, '/');
session_name("SessionBork_Test_session");
session_start();
if (empty($_SESSION["token"])) regenerateToken();
// Complicate session highjacking - check the current user agent against the one that initiated the session.
if (md5($_SERVER["HTTP_USER_AGENT"]) != $_SESSION["userAgent"])
session_destroy();
// Log in a the user based on the SentryUserId
// ... logging in, setting userId, regenerating session
$_SESSION["userId"] = '10';
regenerateToken();
header('Content-Type: text/plain');
foreach ($_SESSION as $k => $v) {
echo $k . " = " . $v . "\n";
}
if ( ! isset($_SESSION['SentryUserId'])) echo "\n--\nPrerendering brokeded me.";
IDE などで xdebug に接続できる場合は、隠し prerender が test2.php にヒットし (これは応答で完全に正しいように見えます)、Enter キーを押すと、その後の実際のヒットが表示されます。あなたは。