6

PHPで行われたダイジェスト認証からログアウトする方法はありますか?

unset($_SERVER["PHP_AUTH_DIGEST"]); を試しました。ただし、再ログインを求められることはありません。ブラウザを閉じると機能することはわかっています。ここに私の機能があります。

    function login(){
        $realm = "Restricted area";
        $users = array("jamesm"=>"");
        if (empty($_SERVER["PHP_AUTH_DIGEST"])) {
            header("HTTP/1.1 401 Unauthorized");
            header("WWW-Authenticate: Digest realm=\"{$realm}\",qop=\"auth\",nonce=\"".uniqid()."\",opaque=\"".md5($realm)."\"");
            return false;
        }
        if (!($data = http_digest_parse($_SERVER["PHP_AUTH_DIGEST"])) || !isset($users[$data["username"]]))
            return false;
        $A1 = md5($data["username"] . ":{$realm}:{$users[$data["username"]]}");
        $A2 = md5($_SERVER["REQUEST_METHOD"].":{$data["uri"]}");
        $valid_response = md5("{$A1}:{$data["nonce"]}:{$data["nc"]}:{$data["cnonce"]}:{$data["qop"]}:{$A2}");
        if ($data["response"] != $valid_response)
            return false;
        return true;
    }
    function logout(){
        unset($_SERVER["PHP_AUTH_DIGEST"]);
        return true;
    }

これを完了するには、ログアウト機能にさらに何を追加する必要がありますか。

レルムを変更すると機能しますが、変更したくありません。

4

2 に答える 2

11

$_SERVER['PHP_AUTH_DIGEST'] の設定を解除しても効果はありません。問題は、設定したタスクに対する「適切な」答えが実際には存在しないことです。

HTTP 仕様では技術的に許可されていませんが、実際には、別の 401 を送信すると、ブラウザのほとんどは事実上「ユーザーをログアウト」します。php.net/http-auth によると:

Netscape Navigator と Internet Explorer はどちらも、401 のサーバー応答を受信すると、レルムのローカル ブラウザー ウィンドウの認証キャッシュをクリアします。これを使用して、ログインを「タイムアウト」したり、「ログアウト」ボタンを提供したりする人もいます。

あなたのコードから、最も簡単な方法はおそらく次のようなものです。

function logout(){
    header('HTTP/1.1 401 Unauthorized');
    return true;
}

ただし、これは実際には HTTP 仕様で承認されているものではありません。

于 2011-01-05T05:04:36.867 に答える
6

正式な回答: http://tools.ietf.org/id/draft-ietf-httpbis-p7-auth-12.txt - セクション 6.1
信頼できる方法はありません。

いくつかの回避策には、401 を偽造して realm= を変更するか、意図的に無効な資格情報を使用して AJAX 認証要求を承認することが含まれます。

于 2011-01-05T05:03:36.003 に答える