PHP摘要认证,注销

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;
    }

我需要在注销功能中添加什么才能完成这个操作。

如果我更改领域,它可以工作,但我不想更改它。


重复的问题:通过PHP进行HTTP身份验证注销。答案:不行。 - netcoder
我知道这个可以做到,只是不太确定具体的方法。 - JamesM-SiteGen
关闭浏览器是唯一的方法,因为信息已经注册在浏览器内部。 - ajreal
2个回答

10

取消 $_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规范所批准的。


1
它可以工作,但注销页面要求重新登录。而且无法通过它登录。事实上,我根本无法登录。噢,它确实让我退出了,但无法再次登录。它还必须只提供header("HTTP/1.1 401 Unauthorized");没有www-autherticate。 - JamesM-SiteGen
很好知道,我不确定Digest是否需要 - 我还没有在自己的任何项目中实现Digest。 - TML
我发现像下面这样的东西对我来说完全没问题:http://codepad.org/BUJvSmnm请注意,在我的情况下,我发现至少有一个浏览器(Firefox 3.6)在logout()中需要WWW-Authenticate头,因此我将生成的uniqid()持久化到$_SESSION中以便在logout头中使用。 - TML
我错了,它仍然需要www-autherticate,我正在测试下面的答案。 - JamesM-SiteGen

5

值得注意的是,该IETF草案文档中相关部分为6.1:身份验证凭据和空闲客户端。 - TML
@JamesM:您需要通过jQuery来启动此操作,以免显示登录对话框。请求一个单独的 logout1.php 文件,例如发送 header("Status:401 Logout")header("WWW-Authenticate: Invalidate, Basic realm=logout")。可选地,再进行第二个AJAX调用,使用无效凭据到 logout2.php,并在不检查的情况下确认它。 - mario
Mario,“状态:401注销”或“HTTP/1.1 401注销”它们有区别吗? - JamesM-SiteGen
你能否将它作为一个经过测试的工作答案发送给摘要,你的评论只是针对基础部分,它适用于摘要吗? - JamesM-SiteGen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接