PHP Digest auth, logout
Asked Answered
P

2

6

Is there a way to logout of a digest authentication done in php.

I have tried unset($_SERVER["PHP_AUTH_DIGEST"]); But it wont ask to relogin. I know if i close the browser then it will work and here are my functions.

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

What more do i need to add to the logout function to finish this off.

If i change the realm it works but i don't want it to be changed.

Pretty answered 5/1, 2011 at 4:43 Comment(3)
Duplicate of HTTP authentication logout via PHP. The answer: No.Vanscoy
I know it can be done, just not sure how.Pretty
close the browser is the only way, as the information is registered inside browserGaitan
C
10

Unsetting $_SERVER['PHP_AUTH_DIGEST'] will have no effect. The problem is, there's not really a "good" answer to the task you've set.

The HTTP specification doesn't technically allow for it, but in practice, most of the browsers out there will effectively "log the user out" if you send them another 401. Per php.net/http-auth:

Both Netscape Navigator and Internet Explorer will clear the local browser window's authentication cache for the realm upon receiving a server response of 401. This can effectively "log out" a user, forcing them to re-enter their username and password. Some people use this to "time out" logins, or provide a "log-out" button.

From your code, the simplest method is probably something like:

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

but, again, this is not actually something approved of by the HTTP specification.

Canadianism answered 5/1, 2011 at 5:4 Comment(4)
It works but the logout page asks to login. and can't login via it. In fact, i can't login at all. oh it logged me out alright just can't login again. It also had to only give header("HTTP/1.1 401 Unauthorized"); no www-autherticate again.Pretty
Good to know, I wasn't sure if Digest required that - I haven't implemented Digest in anything of my own yet.Canadianism
I find that something like the following works just fine for me: codepad.org/BUJvSmnm Note that, in my case, I found at least one browser (Firefox 3.6) that DID require the WWW-Authenticate header in logout(), so I'm persisting the generated uniqid() in $_SESSION for use in the logout header.Canadianism
i was wrong, it still needs the www-autherticate, i'm testing out below answerPretty
S
5

Authoritative answer: http://tools.ietf.org/id/draft-ietf-httpbis-p7-auth-12.txt - section 6.1
There is no reliable way.

Some workarounds include faking a 401 and changing the realm=, or acknowledging an AJAX auth request with purposefully invalid credentials.

Shreeves answered 5/1, 2011 at 5:3 Comment(4)
It's probably worth noting that the relevant section of this IETF Draft document is 6.1: Authentication Credentials and Idle ClientsCanadianism
@JamesM: You need to initiate this via jQuery to not show a login dialog. Request a separate logout1.php which e.g. sends header("Status:401 Logout") and header("WWW-Authenticate: Invalidate, Basic realm=logout"). Optionally a second AJAX call with invalid credentials to logout2.php which acknowledges it without checking.Shreeves
Mario, Status: 401 logout or HTTP/1.1 401 Logout are they different?Pretty
can you send it as a working tested answer for Digest, your comment is for basic, will it work for digest?Pretty

© 2022 - 2024 — McMap. All rights reserved.