ChatGPT解决这个技术问题 Extra ChatGPT

http basic authentication "log out"

HTTP basic authentication credentials are stored until the browser is closed, but is there a way to remove the credentials before the browser is closed?

I read about a trick with HTTP 401 status code, but it seems to work not properly (see comment to answer). Maybe the mechanism trac uses is the solution.

Can the credentials be deleted with JavaScript? Or with a combination of JavaScript and the status 401 trick?

Duplicate of How to log out user from web site using BASIC authentication?. It would be good to consolidate the info into a single place.

L
Luc

Update: This solution does not seem to work anymore in many browsers. Kaitsu's comment:

This solution of sending false credentials to make browser forget the correct authenticated credentials doesn't work in Chrome (16) and IE (9). Works in Firefox (9).

Actually you can implement a workaround by sending false credentials to the service. This works in Browsers by sending another (non-existent?) Username without a password. The Browser loses the information about the authenticated credentials.

Example:

https://www.example.com/ => Log in with basic auth as "user1" Now open https://foobar@www.example.com/ You're Logged out. ;)

Regards

P.s.: But please test this with all needed Browsers before you rely on the given information.


@ajreal: when you hit "back", then you see a cached version of the page. try reload.. (at least in FF and chrome! I guess in other browsers, too)
ajreal: I say it again: once you send a new (not yet authenticated username "foobar") to the server like in my example, then the browser purges the authentication info for the valid info ("user1"). no matter what page you're accessing after that - you will be prompted to authenticate again! Just try it! It works! Make sure you didn't save credentials on your testing server.
This solution of sending false credentials to make browser forget the correct authenticated credentials doesn't work in Chrome (16) and IE (9). Works in Firefox (9). So, not a very usable solution.
Navigating to foobar@www.example.com is treated as a possible phishing attempt. IE and other browsers are probably ignoring the request for security reasons.
The Question and the Answer is from 2010. Time changes Versions and versions may change some behaviour. I clearly stated to test the results before relying on the answer.
1
1n5aN1aC

Expanding on Jan.'s answer, and updating owyongsk's answer:

Here is some example jquery java-script code to cause the browser to essentially send a bogus login request to the page your trying to protect, which in all tested browsers caused the cached credentials to be removed, then redirects the user to a non-protected page.

The alert() when something goes wrong should probably be changed to something else.

//Submits an invalid authentication header, causing the user to be 'logged out'
function logout() {
    $.ajax({
        type: "GET",
        url: "PUT_YOUR_PROTECTED_URL_HERE",
        dataType: 'json',
        async: true,
        username: "some_username_that_doesn't_exist",
        password: "any_stupid_password",
        data: '{ "comment" }'
    })
//In our case, we WANT to get access denied, so a success would be a failure.
.done(function(){
    alert('Error!')
})
//Likewise, a failure *usually* means we succeeded.
//set window.location to redirect the user to wherever you want them to go
.fail(function(){
    window.location = "/";
    });
}

Then it was as easy as just having the logout link call the logout() function, and it seemed to work seamlessly to the user, though it is still technically a hack job.


tested with Chrome 54, Firefox 50, IExplorer 11, Edge 38.14393, works great (Dec 2016).
Fantastic! Thanks a lot.
o
owyongsk

You can try a hack that is working at the moment with the latest Chrome and Firefox. Create a "/logout" page on your server which accepts only a certain credential such as username: false, password: false. Then using this AJAX request below, you can send the user to that page.

  $("#logout").click(function(e){                                              
    e.preventDefault();                                                        
    var request = new XMLHttpRequest();                                        
    request.open("get", "/logout", false, "false", "false");                                                                                                                               
    request.send();                                                            
    window.location.replace("WHEREVER YOU WANT YOUR LOGGED OUT USER TO GO");                                              
  });

What happens is that the false username and password is cached from the valid XMLHttpRequest instead of the current user's credentials, and when a user tries to login into any page, it will use the cached fake credentials, failing to authenticate, it will ask the user to enter another one. Hope this helps!


Probably different versions of Chrome or Firefox than I used then. I'm not maintaining this code anymore, so I can't help ya
@Pies Try the code in this answer below. I haven't tested it but it says it is an update of this answer. The redirect occurs only after the AJAX request has completed which should help.
This works like a charm in the latest Chrome. I have a python-based flask server. When they go to the logout page I check and return success only if the creds are "false", "false". This way the browser caches that instead.
E
Erwin

just finishing an implementation that worked fine to me: At the server I evaluate Session, User Name and password, so I keep track of that information, the login algoritm is as follows:

1.Check if user and password is not empty, else return 401.

2.Check if we have registered the session in our logged-in user list, if not then check if user and password is valid and if so save session id in our list, then return 401. I'll explain this step: if the session id is different one of three things happened: a) The user is opening another window. b) The user session has finished, ie user logged out. c) The session expired due to inactivity. But we want to save the session as long as the user credentials are valid but return a 401 to ask once for password, if we don't save the session then the user could never log in because we don't have the new session id in our list.

3.Check if user credentials are right, if so, save session info and continue serving pages, else return 401.

So, the only thing I have to logout a user is to close the session at the server when the user requests the logout page and the web browser shows again the login dialog.

I'm thinking as I write this that there has to be a step where the program checks if the user is already logged to avoid impersonation, maybe I can save more than one session id per user to allow multiple session, well, I would like your comments about it.

Hope you get the idea, and comment if you see any security flaw ;)


This would seem to require the user to login twice if the browser doesn't have their credentials stored on the initial attempt - is that correct?
V
Vilius Gaidelis

You can delete credentials with JavaScript:

    $("#logout").click(function(){
        try {
            document.execCommand("ClearAuthenticationCache");
            window.location.href('/logout.html'); // page with logout message somewhere in not protected directory
        } catch (exception) {}
    });

This code works only in IE. This is the reason why try/catch block is added there. Also, for the same reason the logout link you should show for IE users only:

    <!--[if IE]>
        <div id="logout">[Logout]</div>
    <![endif]-->

And for other users my suggestion is something like:

    <div id="logout2" onclick="alert('Please close your browser window to logout')">[Logout]</div>

Works in IE9, thanks! Do you happen to know of similar solutions in Firefox, Chrome or other browsers?
G
Greg T

If you have control over the server code, you can create a "logout" function that replies "401 Unauthorized" regardless of the credentials given. This failure forces browsers to remove saved credentials.

I just tested this with Chrome 34, IE 11, Firefox 25 - using Express.js server and HTTP basic authentication.


doesn't seem to work in Safari 7. This beast holds onto credentials no matter what
what seems to work is using wrong credentials. If I do that in the location bar, I get a 'phising warning' from Safari ;) Have yet to test it via ajax
T
Thomas

What has worked for me in Chrome (Version 66) is to send an Ajax request to an URL that returns 401. That way the basic authentication cache seems to be cleared.

var xhttp = new XMLHttpRequest();
xhttp.open("GET", "/url_that_returns_401", true);
xhttp.send();

M
Maqsud Erjonov

This codes worked for me in Chrome (version 83):

var xhttp = new XMLHttpRequest(); 
xhttp.open("GET", "/url_that_return_401", true); 
xhttp.setRequestHeader('Authorization', 'Basic '); 
xhttp.send();

Need to execute this code (maybe by button click or console window) and then prompt appeared, you need to press Cancel button. Then authentication fields clears and you can refresh page and login in with another credentials.


I'm getting a 401 back, but then when I try to subsequently send another request, it somehow is magically sending the correct credentials again.
Y
Yetti99

Mark the nonce as invalid. I did an Ajax call to the server side asking to logout. The server side gets the "Authenticate: Digest..." request in a header. It extracts the nonce="" from that line and adds it to a list of disabled nonces. So next time the browser sends that a request with that "Authenticate: Digest..." line the server replies with 401. This makes the browser ask the user for a new userid/password.

Works fine for my application but only for Digest authentication.