Jak wylogować użytkownika ze strony internetowej przy użyciu uwierzytelnienia BASIC?

279

Czy można wylogować użytkownika ze strony internetowej, jeśli korzysta on z podstawowego uwierzytelnienia?

Sesja zabijania nie wystarczy, ponieważ po uwierzytelnieniu użytkownika każde żądanie zawiera dane logowania, więc użytkownik jest automatycznie logowany przy następnym dostępie do witryny przy użyciu tych samych danych logowania.

Jak dotąd jedynym rozwiązaniem jest zamknięcie przeglądarki, ale z punktu widzenia użyteczności jest to nie do przyjęcia.

Marko
źródło
1
Po prostu ciekawy. Dlaczego chcesz to zrobić?
DOK
17
Aby móc zalogować się jako inny użytkownik.
Marko
16
@DOK - To standardowa funkcja hakowania społecznościowego: użytkownicy powinni mieć możliwość wylogowania się, pozostawiając otwartą przeglądarkę. Załóżmy, że jeden z Twoich użytkowników uzyskuje dostęp do witryny na komputerze publicznym? Muszą się wylogować, aby następny użytkownik nie mógł uzyskać dostępu do witryny jako oni.
Keith,
@DOK Istnieje również problem polegający na tym, że uniemożliwia użytkownikowi wylogowanie się z witryny. Serwer może wyczyścić plik cookie autoryzacji, a nawet plik cookie sesji. Ale gdy przeglądarka przejdzie do ładowania /strony, zostaną automatycznie ponownie zalogowani.
Ian Boyd
Używam metody, która wysyła fałszywe żądanie wylogowania, ale blokuje użytkownika w kliencie, ponieważ istnieje ostre ograniczenie, że 3 razy logowanie nie powiodło się w AD. Dlatego sugeruj ostrożność przy użyciu tej metody (wysyłanie fałszywego żądania).
Qianchao Pan

Odpowiedzi:

170

Podstawowe uwierzytelnianie nie zostało zaprojektowane do zarządzania wylogowaniem. Możesz to zrobić, ale nie całkowicie automatycznie.

Musisz tylko kliknąć link wylogowania i wysłać odpowiedź „401 Nieautoryzowany”, korzystając z tej samej dziedziny i na tym samym poziomie folderu URL, co zwykły numer 401 wysyłany z prośbą o zalogowanie.

Muszą zostać poproszeni o podanie nieprawidłowych danych uwierzytelniających, np. pusta nazwa użytkownika i hasło, a w odpowiedzi odsyłasz stronę „Wylogowanie się powiodło”. Błędne / puste poświadczenia zastąpią poprzednie poprawne poświadczenia.

Krótko mówiąc, skrypt wylogowania odwraca logikę skryptu logowania, zwracając stronę sukcesu tylko wtedy, gdy użytkownik nie przejdzie odpowiednich poświadczeń.

Pytanie brzmi, czy nieco dziwne okno hasła „nie wprowadzaj hasła” spotka się z akceptacją użytkownika. Menedżerowie haseł, którzy próbują automatycznie uzupełnić hasło, również mogą przeszkodzić tutaj.

Edytuj, aby dodać w odpowiedzi na komentarz: ponowne zalogowanie jest nieco innym problemem (chyba że potrzebujesz oczywiście dwuetapowego wylogowania / logowania). Musisz odrzucić (401) pierwszą próbę dostępu do linku ponownego logowania, niż zaakceptować drugą (która prawdopodobnie ma inną nazwę użytkownika / hasło). Można to zrobić na kilka sposobów. Jednym z nich byłoby dołączenie bieżącej nazwy użytkownika do linku wylogowania (np. / Relogin? Nazwa użytkownika) i odrzucenie, gdy poświadczenia są zgodne z nazwą użytkownika.

Bobin
źródło
2
Spróbuję tego podejścia. Celem wylogowania (w tym przypadku) jest umożliwienie użytkownikowi zalogowania się jako inny użytkownik, więc jest to całkowicie akceptowalne rozwiązanie. Jeśli chodzi o hasło autouzupełniania, od użytkownika zależy, czy będzie go używał, czy nie. Dzięki
Marko
Czy to wciąż jedyny sposób? Zrobiłem implementację ASP.Net MVC i jQuery, która działa, ale nadal nie jestem z tego zadowolony: stackoverflow.com/questions/6277919
Keith
@Keith: Wciąż tylko to i odpowiedź systemPAUSE (która nie działa we wszystkich przeglądarkach, ale jest płynniejsza niż ręczne podejście, gdy działa).
bobince
16
W3C jest tak aktywny w specyfikacji HTML. Ale specyfikacja HTTP słabnie. W3C powinien był rozwiązać ten problem około dwie dekady temu. Wraz ze wzrostem korzystania z usług REST potrzebna jest solidna natywna metoda uwierzytelniania.
Dojo
9
Nie działa to poprawnie w przeglądarce Chrome 46 na localhost. Wygląda na to, że Chrome zachowuje zarówno stare (prawidłowe) hasło, jak i nowe hasło, które określisz. Po przejściu na stronę wylogowania Chrome poprawnie używa nowego hasła, AŻ DO SPOTKAŃ IT 401 NIEAUTORYZOWANYCH NA STRONIE NA TWOJEJ STRONIE. Po pierwszym 401 Chrome powraca do starego (poprawnego) hasła. Tak naprawdę to tak naprawdę nie usunęło hasła.
vancan1ty
196

Dodatek do odpowiedzi bobince ...

Dzięki Ajax możesz połączyć link / przycisk „Wyloguj” z funkcją Javascript. Niech ta funkcja wyśle ​​XMLHttpRequest z niepoprawną nazwą użytkownika i hasłem. To powinno odzyskać 401. Następnie ustaw document.location z powrotem na stronę przed logowaniem. W ten sposób użytkownik nigdy nie zobaczy dodatkowego okna logowania podczas wylogowywania, ani nie będzie musiał pamiętać o wprowadzeniu złych danych logowania.

system PAUZA
źródło
12
Dobry hack, ręczne wprowadzanie złych danych uwierzytelniających użytkownika jest prawdopodobnie nie do przyjęcia dla większości aplikacji internetowych.
BillMan
1
Upewnij się tylko, że XMLHttpRequest nie jest ustawiony jako asynchroniczny, ponieważ możesz przekierować, że nastąpi przekierowanie przed zakończeniem żądania wylogowania.
davidjb
5
Możesz użyć tej samej sztuczki również do logowania. W ten sposób można dostosować okno dialogowe logowania bez konieczności zmiany metody uwierzytelniania serwera. W tym artykule podano kilka dobrych pomysłów: http://www.peej.co.uk/articles/http-auth-with-html-forms.html
Stijn de Witt
1
@davidjb Ponieważ żądania synchroniczne są obecnie uznawane za przestarzałe, alternatywnym rozwiązaniem może być przekierowanie użytkownika w wywołaniu zwrotnym żądania asynchronicznego.
Hayden Schiff,
1
David: chrome pozwala teraz na XHR i mogę potwierdzić, że nadal działa na kanale chrome. bugs.chromium.org/p/chromium/issues/detail?id=435547
CpnCrunch
192

Poproś użytkownika o kliknięcie linku do https: // log: [email protected]/ . Spowoduje to zastąpienie istniejących poświadczeń nieprawidłowymi; wylogowanie ich.

Matthew Welborn
źródło
19
Dlaczego ten nie ma więcej głosów pozytywnych? Wydaje mi się to prostym i działającym rozwiązaniem. Czy są jakieś znane problemy z tym podejściem?
amoebe
35
Nie działałoby to już w Chrome, który ze względów bezpieczeństwa ignoruje poświadczenia w adresie URL.
Thom
5
To zadziałało dla mnie :) Korzystam z wersji Chrome 32.0.1700.102
abottoni
6
problem: przy użyciu wersji 39.0 chrome, kiedy klikam link wylogowania za pomocą tej metody, Chrome zapamiętuje złe dane logowania i wyświetla monit o nowe dane logowania przy każdym ładowaniu strony, dopóki nie przejdę do example.com bez żadnych danych logowania, aby wyczyść pamięć chrome.
Scott
4
Cześć, nie mogę go używać do https w Chrome.
thienkhoi tran
67

Możesz to zrobić całkowicie w JavaScript:

IE ma (przez długi czas) standardowy interfejs API do czyszczenia pamięci podręcznej podstawowego uwierzytelniania:

document.execCommand("ClearAuthenticationCache")

Powinien zwrócić wartość true, gdy działa. Zwraca wartość false, niezdefiniowany lub wysadza się w innych przeglądarkach.

Nowe przeglądarki (od grudnia 2012 r .: Chrome, FireFox, Safari) działają „magicznie”. Jeśli zobaczą udane podstawowe żądanie autoryzacji z dowolną inną fałszywą nazwą użytkownika (powiedzmy logout), usuwają pamięć podręczną poświadczeń i ewentualnie ustawiają ją dla tej nowej fałszywej nazwy użytkownika, którą musisz upewnić się, że nie jest prawidłową nazwą użytkownika do przeglądania treści.

Podstawowym przykładem tego jest:

var p = window.location.protocol + '//'
// current location must return 200 OK for this GET
window.location = window.location.href.replace(p, p + 'logout:password@')

„Asynchronicznym” sposobem wykonania powyższego jest wykonanie wywołania AJAX przy użyciu logoutnazwy użytkownika. Przykład:

(function(safeLocation){
    var outcome, u, m = "You should be logged out now.";
    // IE has a simple solution for it - API:
    try { outcome = document.execCommand("ClearAuthenticationCache") }catch(e){}
    // Other browsers need a larger solution - AJAX call with special user name - 'logout'.
    if (!outcome) {
        // Let's create an xmlhttp object
        outcome = (function(x){
            if (x) {
                // the reason we use "random" value for password is 
                // that browsers cache requests. changing
                // password effectively behaves like cache-busing.
                x.open("HEAD", safeLocation || location.href, true, "logout", (new Date()).getTime().toString())
                x.send("")
                // x.abort()
                return 1 // this is **speculative** "We are done." 
            } else {
                return
            }
        })(window.XMLHttpRequest ? new window.XMLHttpRequest() : ( window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : u ))
    }
    if (!outcome) {
        m = "Your browser is too old or too weird to support log out functionality. Close all windows and restart the browser."
    }
    alert(m)
    // return !!outcome
})(/*if present URI does not return 200 OK for GET, set some other 200 OK location here*/)

Możesz też zrobić z niego bookmarklet:

javascript:(function(c){var a,b="You should be logged out now.";try{a=document.execCommand("ClearAuthenticationCache")}catch(d){}a||((a=window.XMLHttpRequest?new window.XMLHttpRequest:window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):void 0)?(a.open("HEAD",c||location.href,!0,"logout",(new Date).getTime().toString()),a.send(""),a=1):a=void 0);a||(b="Your browser is too old or too weird to support log out functionality. Close all windows and restart the browser.");alert(b)})(/*pass safeLocation here if you need*/);

ddotsenko
źródło
1
Czy wymaga to specjalnej obsługi logoutnazwy użytkownika i / lub adresu URL wylogowania po stronie serwera ?
ulidtko
1
@ulidtko Nie, nie powinno - cała obsługa odbywa się po stronie klienta. Jedyną sytuacją, która wymagałaby specjalnej obsługi, jest sytuacja, w której wywoływany użytkownik logoutistnieje i ma wygenerowane hasło. W tym prawie niemożliwie rzadkim przypadku zmień identyfikator użytkownika na taki, który nie będzie istniał w twoim systemie.
davidjb
2
Użyłem dziś bookmarkletu powyżej i działam dobrze.
David Gleba
Użyłem tego i działało to dla Chrome i FF. Musiałem tylko zrobić dodatkowe „GET” na mojej stronie logout.php, aby wyczyścić $ _SESSION.
miejski
2
Bookmarklet działa również na Edge. Po prostu użyj z<a href='javascript:......need*/);'>Logout</a>
Eric
21

Potwierdzono działanie następującej funkcji dla Firefox 40, Chrome 44, Opera 31 i IE 11.
Bowser służy do wykrywania przeglądarki, jQuery jest również używany.

- secUrl to adres URL obszaru chronionego hasłem, z którego należy się wylogować.
- redirUrl to adres URL do obszaru niechronionego hasłem (strona udanego wylogowania).
- możesz zwiększyć czas przekierowania (obecnie 200 ms).

function logout(secUrl, redirUrl) {
    if (bowser.msie) {
        document.execCommand('ClearAuthenticationCache', 'false');
    } else if (bowser.gecko) {
        $.ajax({
            async: false,
            url: secUrl,
            type: 'GET',
            username: 'logout'
        });
    } else if (bowser.webkit) {
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.open("GET", secUrl, true);
        xmlhttp.setRequestHeader("Authorization", "Basic logout");
        xmlhttp.send();
    } else {
        alert("Logging out automatically is unsupported for " + bowser.name
            + "\nYou must close the browser to log out.");
    }
    setTimeout(function () {
        window.location.href = redirUrl;
    }, 200);
}

mthoring
źródło
to jest najbardziej wyczerpująca odpowiedź
belidzs
Czy jest jakiś powód, dla którego $.ajaxwariant jest synchroniczny ( async: false), a xmlhttpwariant jest asynchroniczny ( truein open())?
Bowi,
1
Chrome używa teraz silnika renderowania Blink, więc musisz się zmienić (bowser.gecko)na (bowser.gecko || bowser.blink).
Bowi
1
Dlaczego używa się Gecko / Blink $.ajaxi Webkit new XMLHttpRequest? Czy gecko / blink nie powinien być w stanie zrobić, XMLHttpRequesta webkit $.ajaxtakże? Jestem zmieszany.
RemyNL
11

Oto bardzo prosty przykład Javascript za pomocą jQuery:

function logout(to_url) {
    var out = window.location.href.replace(/:\/\//, '://log:out@');

    jQuery.get(out).error(function() {
        window.location = to_url;
    });
}

Ten użytkownik dziennika bez pokazując mu przeglądarkę dziennika w oknie ponownie, a następnie przekierować go do wylogowany stronę

Romuald Brunet
źródło
1
window.location = window.location.href.replace (/: \ / \ //, ': // log: out @');
sebhaase
10

Nie jest to bezpośrednio możliwe w przypadku podstawowego uwierzytelnienia.

W specyfikacji HTTP nie ma mechanizmu informującego przeglądarkę, aby przestała wysyłać poświadczenia, które użytkownik już przedstawił.

Istnieją „włamania” (patrz inne odpowiedzi), zwykle polegające na użyciu XMLHttpRequest w celu wysłania żądania HTTP z niepoprawnymi danymi uwierzytelniającymi w celu zastąpienia oryginalnie podanych.

Alnitak
źródło
12
W teorii. Praktyka dowodzi inaczej, jak wynika z innych odpowiedzi.
Stijn de Witt
2
Jak widać z innych odpowiedzi, nie w sposób niezawodny, spójny i bezpieczny w razie awarii!
jplandrain
5

Działa to dla IE / Netscape / Chrome:

      function ClearAuthentication(LogOffPage) 
  {
     var IsInternetExplorer = false;    

     try
     {
         var agt=navigator.userAgent.toLowerCase();
         if (agt.indexOf("msie") != -1) { IsInternetExplorer = true; }
     }
     catch(e)
     {
         IsInternetExplorer = false;    
     };

     if (IsInternetExplorer) 
     {
        // Logoff Internet Explorer
        document.execCommand("ClearAuthenticationCache");
        window.location = LogOffPage;
     }
     else 
     {
        // Logoff every other browsers
    $.ajax({
         username: 'unknown',
         password: 'WrongPassword',
             url: './cgi-bin/PrimoCgi',
         type: 'GET',
         beforeSend: function(xhr)
                 {
            xhr.setRequestHeader("Authorization", "Basic AAAAAAAAAAAAAAAAAAA=");
         },

                 error: function(err)
                 {
                    window.location = LogOffPage;
             }
    });
     }
  }


  $(document).ready(function () 
  {
      $('#Btn1').click(function () 
      {
         // Call Clear Authentication 
         ClearAuthentication("force_logout.html"); 
      });
  });          
Claudio
źródło
5

To jest właściwie całkiem proste.

Wystarczy odwiedzić stronę w przeglądarce i użyć nieprawidłowych danych logowania: http: // nazwa użytkownika: hasł[email protected]

To powinno „wylogować”.

Chiedo
źródło
1
Ale użytkownik musi być PRAWDZIWYM użytkownikiem, w przeciwnym razie dostaję komunikat „401 Nieautoryzowany”, ale za pomocą przycisku WSTECZ mogę kontynuować pracę jako wcześniej zalogowany użytkownik. Testowane na serwerze internetowym Abyss X1 (2.11.1)
2956477,
1
Duplikat odpowiedzi (patrz powyżej Matthew Welborn).
Skippy le Grand Gourou,
3

Wystarczy przekierować użytkownika na adres URL wylogowania i zwrócić 401 Unauthorizedbłąd. Na stronie błędu (która musi być dostępna bez podstawowego uwierzytelnienia) musisz podać pełny link do swojej strony głównej (w tym schemat i nazwę hosta). Użytkownik kliknie ten link, a przeglądarka ponownie poprosi o poświadczenia.

Przykład dla Nginx:

location /logout {
    return 401;
}

error_page 401 /errors/401.html;

location /errors {
    auth_basic off;
    ssi        on;
    ssi_types  text/html;
    alias /home/user/errors;
}

Strona błędu /home/user/errors/401.html:

<!DOCTYPE html>
<p>You're not authorised. <a href="<!--# echo var="scheme" -->://<!--# echo var="host" -->/">Login</a>.</p>
Envek
źródło
Chciałbym dodatkowo zalecamy użycie http_hostw 401.htmlzamiast po prostu host, jako dawny dodaje również numer portu (w przypadku jest używany niestandardowy port)
Emil Koutanov
2
function logout() {
  var userAgent = navigator.userAgent.toLowerCase();

  if (userAgent.indexOf("msie") != -1) {
    document.execCommand("ClearAuthenticationCache", false);
  }

  xhr_objectCarte = null;

  if(window.XMLHttpRequest)
    xhr_object = new XMLHttpRequest();
  else if(window.ActiveXObject)
    xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
  else
    alert ("Your browser doesn't support XMLHTTPREQUEST");

  xhr_object.open ('GET', 'http://yourserver.com/rep/index.php', false, 'username', 'password');
  xhr_object.send ("");
  xhr_object = null;

  document.location = 'http://yourserver.com'; 
  return false;
}
Charlie
źródło
2
 function logout(url){
    var str = url.replace("http://", "http://" + new Date().getTime() + "@");
    var xmlhttp;
    if (window.XMLHttpRequest) xmlhttp=new XMLHttpRequest();
    else xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    xmlhttp.onreadystatechange=function()
    {
        if (xmlhttp.readyState==4) location.reload();
    }
    xmlhttp.open("GET",str,true);
    xmlhttp.setRequestHeader("Authorization","Basic xxxxxxxxxx")
    xmlhttp.send();
    return false;
}
Sushovan Mukherjee
źródło
2

Na podstawie tego, co przeczytałem powyżej, otrzymałem proste rozwiązanie, które działa w dowolnej przeglądarce:

1) na stronie wylogowania wywołujesz ajax do swojego zaplecza logowania. Twój zaplecze logowania musi zaakceptować użytkownika wylogowania. Po zaakceptowaniu zaplecza przeglądarka wyczyści bieżącego użytkownika i przyjmie użytkownika „wylogowania”.

$.ajax({
    async: false,
    url: 'http://your_login_backend',
    type: 'GET',
    username: 'logout'
});      

setTimeout(function () {
    window.location.href = 'http://normal_index';
}, 200);

2) Teraz, gdy użytkownik powróci do normalnego pliku indeksu, spróbuje automatycznie wejść do systemu z użytkownikiem „wyloguj się”, po raz drugi musisz go zablokować, odpowiadając 401, aby wywołać okno dialogowe logowania / hasła.

3) Można to zrobić na wiele sposobów, utworzyłem dwa zaplecza logowania, jeden akceptujący użytkownika wylogowania, a drugi nie. Moja normalna strona logowania używa strony, która nie akceptuje, moja strona wylogowania używa strony, która ją akceptuje.

Foad
źródło
2

Właśnie przetestowałem następujące elementy w Chrome (79), Firefox (71) i Edge (44) i działa dobrze. Stosuje rozwiązanie skryptu, jak wspomniano powyżej.

Wystarczy dodać link „Wyloguj się”, a po kliknięciu zwróć następujący HTML

    <div>You have been logged out. Redirecting to home...</div>    

<script>
    var XHR = new XMLHttpRequest();
    XHR.open("GET", "/Home/MyProtectedPage", true, "no user", "no password");
    XHR.send();

    setTimeout(function () {
        window.location.href = "/";
    }, 3000);
</script>
Teo Bebekis
źródło
1

Ten JavaScript musi działać dla wszystkich przeglądarek najnowszej wersji:

//Detect Browser
var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
    // Opera 8.0+ (UA detection to detect Blink/v8-powered Opera)
var isFirefox = typeof InstallTrigger !== 'undefined';   // Firefox 1.0+
var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
    // At least Safari 3+: "[object HTMLElementConstructor]"
var isChrome = !!window.chrome && !isOpera;              // Chrome 1+
var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6
var Host = window.location.host;


//Clear Basic Realm Authentication
if(isIE){
//IE
    document.execCommand("ClearAuthenticationCache");
    window.location = '/';
}
else if(isSafari)
{//Safari. but this works mostly on all browser except chrome
    (function(safeLocation){
        var outcome, u, m = "You should be logged out now.";
        // IE has a simple solution for it - API:
        try { outcome = document.execCommand("ClearAuthenticationCache") }catch(e){}
        // Other browsers need a larger solution - AJAX call with special user name - 'logout'.
        if (!outcome) {
            // Let's create an xmlhttp object
            outcome = (function(x){
                if (x) {
                    // the reason we use "random" value for password is 
                    // that browsers cache requests. changing
                    // password effectively behaves like cache-busing.
                    x.open("HEAD", safeLocation || location.href, true, "logout", (new Date()).getTime().toString())
                    x.send("");
                    // x.abort()
                    return 1 // this is **speculative** "We are done." 
                } else {
                    return
                }
            })(window.XMLHttpRequest ? new window.XMLHttpRequest() : ( window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : u )) 
        }
        if (!outcome) {
            m = "Your browser is too old or too weird to support log out functionality. Close all windows and restart the browser."
        }
        alert(m);
        window.location = '/';
        // return !!outcome
    })(/*if present URI does not return 200 OK for GET, set some other 200 OK location here*/)
}
else{
//Firefox,Chrome
    window.location = 'http://log:out@'+Host+'/';
}
Amit Shah
źródło
1

dodaj to do swojej aplikacji:

@app.route('/logout')
def logout():
    return ('Logout', 401, {'WWW-Authenticate': 'Basic realm="Login required"'})
Amir Mofakhar
źródło
lepiej skorzystać z tego zwrotu: return („Wyloguj się”, 401)
Amir Mofakhar
1

wpisz chrome://restartpasek adresu i chrome, wszystkie aplikacje działające w tle, uruchomią się ponownie i pamięć podręczna haseł Auth zostanie wyczyszczona.

Ali
źródło
1

Dla przypomnienia istnieje nowy nagłówek odpowiedzi HTTP o nazwie Clear-Site-Data. Jeśli odpowiedź serwera zawiera Clear-Site-Data: "cookies"nagłówek, dane uwierzytelniające (nie tylko pliki cookie) powinny zostać usunięte. Testowałem to na Chrome 77, ale to ostrzeżenie pojawia się na konsoli:

Clear-Site-Data header on 'https://localhost:9443/clear': Cleared data types:
"cookies". Clearing channel IDs and HTTP authentication cache is currently not
supported, as it breaks active network connections.

Poświadczenia uwierzytelniania nie są usuwane, więc nie działa (na razie) w celu wdrożenia podstawowych wylogowań uwierzytelniania, ale być może w przyszłości tak się stanie. Nie testowałem w innych przeglądarkach.

Bibliografia:

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Clear-Site-Data

https://www.w3.org/TR/clear-site-data/

https://github.com/w3c/webappsec-clear-site-data

https://caniuse.com/#feat=mdn-http_headers_clear-site-data_cookies

Nahuel Greco
źródło
1

Wysyłanie https://invalid_login@hostnamedziała dobrze wszędzie oprócz Safari na Macu (cóż, nie zaznaczone Edge, ale też powinno tam działać).

Wylogowanie nie działa w przeglądarce Safari, gdy użytkownik wybierze opcję „zapamiętaj hasło” w wyskakującym okienku Uwierzytelnianie podstawowe HTTP. W takim przypadku hasło jest przechowywane w Dostępu do pęku kluczy (Finder> Aplikacje> Narzędzia> Dostęp do pęku kluczy (lub CMD + SPACJA i wpisz „Dostęp do pęku kluczy”)). Wysyłanie https://invalid_login@hostnamenie wpływa na dostęp do pęku kluczy, więc dzięki temu polu wyboru nie można się wylogować w Safari na Macu. Przynajmniej tak to dla mnie działa.

MacOS Mojave (10.14.6), Safari 12.1.2.

Poniższy kod działa dla mnie dobrze w Firefox (73), Chrome (80) i Safari (12). Gdy użytkownik przechodzi do strony wylogowania, kod jest wykonywany i upuszcza poświadczenia.

    //It should return 401, necessary for Safari only
    const logoutUrl = 'https://example.com/logout'; 
    const xmlHttp = new XMLHttpRequest();
    xmlHttp.open('POST', logoutUrl, true, 'logout');
    xmlHttp.send();

Również z jakiegoś powodu Safari nie zapisuje poświadczeń w wyskakującym okienku Podstawowego uwierzytelniania HTTP, nawet jeśli wybrano „zapamiętaj hasło”. Inne przeglądarki robią to poprawnie.

Fogus
źródło
0
  • użyj identyfikatora sesji (ciasteczka)
  • unieważnij identyfikator sesji na serwerze
  • Nie akceptuj użytkowników z nieprawidłowymi identyfikatorami sesji
Tomalak
źródło
Dobrze jest również oferować uwierzytelnianie podstawowe jako zapasowy schemat logowania, gdy pliki cookie nie są dostępne.
bobince
0

Zaktualizowałem rozwiązanie mthoringu dla nowoczesnych wersji Chrome:

function logout(secUrl, redirUrl) {
    if (bowser.msie) {
        document.execCommand('ClearAuthenticationCache', 'false');
    } else if (bowser.gecko) {
        $.ajax({
            async: false,
            url: secUrl,
            type: 'GET',
            username: 'logout'
        });
    } else if (bowser.webkit || bowser.chrome) {
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.open(\"GET\", secUrl, true);
        xmlhttp.setRequestHeader(\"Authorization\", \"Basic logout\");\
        xmlhttp.send();
    } else {
// http://stackoverflow.com/questions/5957822/how-to-clear-basic-authentication-details-in-chrome
        redirUrl = url.replace('http://', 'http://' + new Date().getTime() + '@');
    }
    setTimeout(function () {
        window.location.href = redirUrl;
    }, 200);
}
Max
źródło
-1
    function logout(secUrl, redirUrl) {
        if (bowser.msie) {
            document.execCommand('ClearAuthenticationCache', 'false');
        } else if (bowser.gecko) {
            $.ajax({
                async: false,
                url: secUrl,
                type: 'GET',
                username: 'logout'
            });
        } else if (bowser.webkit) {
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.open("GET", secUrl, true);
            xmlhttp.setRequestHeader("Authorization", "Basic logout");
            xmlhttp.send();
        } else {
            alert("Logging out automatically is unsupported for " + bowser.name
                + "\nYou must close the browser to log out.");
        }
        setTimeout(function () {
            window.location.href = redirUrl;
        }, 200);
    }

źródło