Làm cách nào để đăng xuất người dùng khỏi trang web bằng xác thực BASIC?


279

Có thể đăng xuất người dùng từ một trang web nếu anh ta đang sử dụng xác thực cơ bản?

Giết phiên là không đủ, vì, khi người dùng được xác thực, mỗi yêu cầu chứa thông tin đăng nhập, do đó người dùng sẽ tự động đăng nhập vào lần tiếp theo anh ta / cô ta truy cập trang web bằng cùng thông tin đăng nhập.

Giải pháp duy nhất cho đến nay là đóng trình duyệt, nhưng điều đó không được chấp nhận từ quan điểm khả năng sử dụng.


1
Chỉ tò mò thôi. tại sao bạn muốn làm việc này?
DOK

17
Để có thể đăng nhập như một người dùng khác.
Marko

16
@DOK - Đó là một điều hack xã hội tiêu chuẩn: người dùng sẽ có thể đăng xuất trong khi để trình duyệt của họ mở. Giả sử một trong những người dùng của bạn truy cập trang web trên một máy công cộng? Họ cần phải đăng xuất một cách rõ ràng để người dùng tiếp theo không thể truy cập trang web như họ.
Keith

@DOK Ngoài ra còn có một vấn đề khiến người dùng không thể đăng xuất khỏi trang web. Máy chủ có thể xóa cookie ủy quyền và thậm chí cookie phiên. Nhưng khi trình duyệt tải /trang, chúng sẽ tự động được đăng nhập lại.
Ian Boyd

Tôi sử dụng phương thức gửi yêu cầu giả để đăng xuất, nhưng nó khóa người dùng trong khách hàng vì có một hạn chế khó khăn là 3 lần đăng nhập thất bại trong AD. Vì vậy, đề nghị sử dụng phương pháp này (gửi yêu cầu giả mạo) một cách thận trọng.
Qianchao Pan

Câu trả lời:


170

Xác thực cơ bản không được thiết kế để quản lý đăng xuất. Bạn có thể làm điều đó, nhưng không hoàn toàn tự động.

Những gì bạn phải làm là yêu cầu người dùng nhấp vào liên kết đăng xuất và gửi phản hồi '401 trái phép', sử dụng cùng một lĩnh vực và ở cùng cấp độ thư mục URL như thông thường mà bạn gửi yêu cầu đăng nhập.

Họ phải được chuyển đến thông tin đăng nhập sai tiếp theo, ví dụ. một tên người dùng và mật khẩu trống, và để đáp lại, bạn gửi lại một trang Bạn đã đăng xuất thành công trang. Thông tin đăng nhập sai / trống sau đó sẽ ghi đè thông tin xác thực chính xác trước đó.

Nói tóm lại, tập lệnh đăng xuất sẽ đảo ngược logic của tập lệnh đăng nhập, chỉ trả về trang thành công nếu người dùng không chuyển đúng thông tin đăng nhập.

Câu hỏi đặt ra là liệu có phần nào tò mò không nhập mật khẩu của bạn Hộp mật khẩu của bạn sẽ đáp ứng sự chấp nhận của người dùng hay không. Trình quản lý mật khẩu cố gắng tự động điền mật khẩu cũng có thể theo cách ở đây.

Chỉnh sửa để thêm phản hồi cho nhận xét: đăng nhập lại là một vấn đề hơi khác (trừ khi bạn yêu cầu đăng xuất / đăng nhập hai bước rõ ràng). Bạn phải từ chối (401) lần đầu tiên truy cập vào liên kết relogin, hơn là chấp nhận lần thứ hai (có lẽ có tên người dùng / mật khẩu khác). Có một vài cách bạn có thể làm điều này. Một người sẽ bao gồm tên người dùng hiện tại trong liên kết đăng xuất (ví dụ: / relogin? Tên người dùng) và từ chối khi thông tin đăng nhập khớp với tên người dùng.


2
Tôi sẽ thử phương pháp này. Điểm đăng xuất (trong trường hợp này) là cho phép người dùng đăng nhập với tư cách người dùng khác, vì vậy đây là giải pháp hoàn toàn chấp nhận được. Đối với mật khẩu tự động điền, tùy thuộc vào người dùng nếu anh ta sẽ sử dụng nó hay không. Cảm ơn
Marko

Đây vẫn là cách duy nhất? Tôi đã thực hiện một triển khai ASP.Net MVC và jQuery hoạt động, nhưng tôi vẫn không hài lòng với nó: stackoverflow.com/questions/6277919
Keith

@Keith: Vẫn chỉ có câu trả lời này và systemPAUSE (không hoạt động trên tất cả các trình duyệt, nhưng mượt hơn so với cách tiếp cận thủ công khi nó hoạt động).
bobince

16
W3C rất tích cực trên thông số HTML. Nhưng thông số kỹ thuật HTTP đang mòn mỏi. W3C đã khắc phục vấn đề này khoảng hai thập kỷ trước. Với sự gia tăng sử dụng các dịch vụ REST, một phương thức xác thực riêng mạnh mẽ là cần thiết trong ngày.
Dojo

9
Điều này dường như không hoạt động đúng trong trình duyệt Chrome 46 trên localhost. Chrome dường như giữ cả mật khẩu cũ (chính xác) và mật khẩu mới mà bạn chỉ định. Sau khi điều hướng đến trang đăng xuất, chrome sử dụng chính xác mật khẩu mới UNTIL IT ENCOUNTERS 401 KHÔNG GIỚI HẠN TRÊN TRANG TRÊN TRANG WEB CỦA BẠN. Sau lần đầu tiên 401, Chrome trở lại mật khẩu cũ (chính xác). Vì vậy, nó thực sự đã không xóa mật khẩu ở nơi đầu tiên.
vancan1ty

196

Một bổ sung cho câu trả lời của bobince ...

Với Ajax, bạn có thể kết nối / nút 'Đăng xuất' của mình với chức năng Javascript. Có chức năng này gửi XMLHttpRequest với tên người dùng và mật khẩu xấu. Điều này sẽ lấy lại một 401. Sau đó đặt document.location trở lại trang đăng nhập trước. Bằng cách này, người dùng sẽ không bao giờ thấy hộp thoại đăng nhập thêm trong quá trình đăng xuất, cũng không phải nhớ đặt thông tin xấu.


12
Hack tốt, có người dùng nhập thủ công thông tin xấu có thể không được chấp nhận đối với hầu hết các ứng dụng web.
Billman

1
Chỉ cần đảm bảo rằng XMLHttpRequest không được đặt thành không đồng bộ hoặc bạn có thể thấy rằng việc chuyển hướng qua sẽ diễn ra trước khi yêu cầu đăng xuất hoàn tất.
davidjb

5
Bạn cũng có thể sử dụng thủ thuật tương tự để đăng nhập. Bằng cách đó, bạn có thể tùy chỉnh hộp thoại đăng nhập mà không phải thay đổi phương thức xác thực của máy chủ. Bài viết này cung cấp một số ý tưởng hay: http://www.peej.co.uk/articles/http-auth-with-html-forms.html
Stijn de Witt

1
@davidjb Vì các yêu cầu đồng bộ được coi là không dùng nữa, một giải pháp thay thế có thể là chuyển hướng người dùng trong cuộc gọi lại của yêu cầu không đồng bộ.
Hayden Schiff

1
David: chrome hiện cho phép điều này cho XHRs và tôi có thể xác nhận rằng nó vẫn hoạt động trong chrome canary. bug.chromium.org/p/chromium/issues/detail?id=435547
CpnCrunch

192

Yêu cầu người dùng nhấp vào liên kết tới https: // log: out@example.com/ . Điều đó sẽ ghi đè thông tin đăng nhập hiện có với thông tin không hợp lệ; đăng xuất chúng.


19
Tại sao cái này không nhận được nhiều upvote? Có vẻ như một giải pháp đơn giản và làm việc với tôi. Có bất kỳ vấn đề được biết đến với phương pháp này?
amoebe

35
Điều này sẽ không còn hoạt động trong Chrome, vì lý do bảo mật bỏ qua thông tin đăng nhập trong URL.
Thom

5
Điều này đã làm việc cho tôi :) Tôi đang sử dụng Chrome Phiên bản 32.0.1700.102
abippii

6
vấn đề: sử dụng phiên bản 39.0 của chrome, Khi tôi nhấp vào liên kết đăng xuất thông qua phương thức này, Chrome sẽ nhớ thông tin đăng nhập xấu và nhắc nhở về thông tin đăng nhập mới trên mỗi lần tải trang, cho đến khi tôi truy cập example.com mà không có bất kỳ thông tin đăng nhập cụ thể nào, xóa bộ nhớ của chrome.
Scott

4
Xin chào, tôi không thể sử dụng nó cho https trên Chrome.
thienkhoi tran

67

Bạn có thể làm điều đó hoàn toàn bằng JavaScript:

IE có API tiêu chuẩn (trong một thời gian dài) để xóa bộ đệm Xác thực cơ bản:

document.execCommand("ClearAuthenticationCache")

Nên trả lại đúng khi nó hoạt động. Trả về sai, không xác định hoặc thổi lên trên các trình duyệt khác.

Các trình duyệt mới (kể từ tháng 12 năm 2012: Chrome, FireFox, Safari) có hành vi "ma thuật". Nếu họ thấy một yêu cầu xác thực cơ bản thành công với bất kỳ tên người dùng giả nào khác (giả sử logout), họ sẽ xóa bộ đệm thông tin đăng nhập và có thể đặt nó cho tên người dùng không có thật mới, mà bạn cần chắc chắn rằng đó không phải là tên người dùng hợp lệ để xem nội dung.

Ví dụ cơ bản về điều đó là:

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

Một cách "không đồng bộ" để thực hiện ở trên là thực hiện cuộc gọi AJAX sử dụng logouttên người dùng. Thí dụ:

(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*/)

Bạn cũng có thể biến nó thành 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*/);


1
Điều này có yêu cầu xử lý đặc biệt phía máy chủ của logouttên người dùng và / hoặc URL đăng xuất không?
ulidtko

1
@ulidtko Không, không nên - mọi xử lý đều ở phía khách hàng. Tình huống duy nhất cần xử lý đặc biệt là nếu người dùng được gọi là logouttồn tại và có mật khẩu được tạo. Trong trường hợp gần như không thể tưởng tượng được, hãy thay đổi ID người dùng thành một cái không tồn tại trong hệ thống của bạn.
davidjb

2
Tôi đã sử dụng bookmarklet ở trên ngày hôm nay và tôi làm việc tốt.
David Gleba

Tôi đã sử dụng cái này và nó hoạt động cho Chrome và FF. Tôi chỉ phải thực hiện thêm "NHẬN" trên trang logout.php của mình để xóa $ _SESSION.
đô thị

2
Bookmarklet cũng hoạt động trên Edge. Đơn giản chỉ cần sử dụng với<a href='javascript:......need*/);'>Logout</a>
Eric

21

Chức năng sau được xác nhận hoạt động cho Firefox 40, Chrome 44, Opera 31 và IE 11.
Bowser được sử dụng để phát hiện trình duyệt, jQuery cũng được sử dụng.

- secUrl là url đến một khu vực được bảo vệ bằng mật khẩu để đăng xuất.
- redirUrl là url đến một khu vực không được bảo vệ bằng mật khẩu (trang thành công đăng xuất).
- bạn có thể muốn tăng bộ đếm thời gian chuyển hướng (hiện tại là 200ms).

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


đây là câu trả lời toàn diện nhất
belidzs

Có bất kỳ lý do cho các $.ajaxbiến thể là đồng bộ ( async: false) và xmlhttpbiến thể là không đồng bộ ( truetrong open())?
Bowi

1
Chrome hiện sử dụng công cụ kết xuất Blink, do đó bạn phải đổi (bowser.gecko)sang (bowser.gecko || bowser.blink).
Bowi

1
Tại sao tắc kè / nháy sử dụng $.ajaxvà webkit sử dụng new XMLHttpRequest? Không nên tắc kè / nháy mắt có thể làm được XMLHttpRequestvà webkit cũng có thể làm được $.ajax? Tôi bối rối.
RemyNL

11

Đây là một ví dụ Javascript rất đơn giản sử dụng jQuery:

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

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

Người dùng đăng nhập này mà không hiển thị lại cho anh ta hộp đăng nhập trình duyệt, sau đó chuyển hướng anh ta đến một trang đã đăng xuất


1
window.location = window.location.href.replace (/: \ / \ //, ': // log: out @');
sebhaase

10

Điều này không thể trực tiếp với Xác thực cơ bản.

Không có cơ chế nào trong đặc tả HTTP cho máy chủ để yêu cầu trình duyệt ngừng gửi thông tin đăng nhập mà người dùng đã trình bày.

Có "hack" (xem các câu trả lời khác) thường liên quan đến việc sử dụng XMLHttpRequest để gửi yêu cầu HTTP với thông tin không chính xác để ghi đè lên những câu hỏi được cung cấp ban đầu.


12
Trong lý thuyết. Thực hành chứng minh khác như có thể được nhìn thấy từ các câu trả lời khác.
Stijn de Witt

2
Và như bạn cũng có thể thấy từ các câu trả lời khác, không phải theo cách đáng tin cậy, nhất quán và không an toàn!
jplandrain

5

Điều này đang hoạt động cho 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"); 
      });
  });          

5

Nó thực sự khá đơn giản.

Chỉ cần truy cập vào phần sau trong trình duyệt của bạn và sử dụng thông tin đăng nhập sai: http: // tên người dùng: password@yourdomain.com

Điều đó sẽ "đăng xuất bạn".


1
Nhưng người dùng phải là người dùng THỰC SỰ, ngoài ra tôi đã nhận được "401 trái phép", nhưng sử dụng nút BACK tôi có thể tiếp tục làm việc như một người dùng đã đăng nhập trước đó. Đã thử nghiệm trên máy chủ web Abyss X1 (2.11.1)
user2956477

1
Câu trả lời trùng lặp (xem Matthew Welborn ở trên).
Skippy le Grand Gourou

3

Tất cả những gì bạn cần là chuyển hướng người dùng trên một số URL đăng xuất và trả về 401 Unauthorizedlỗi trên đó. Trên trang lỗi (phải có thể truy cập mà không có auth cơ bản), bạn cần cung cấp một liên kết đầy đủ đến trang chủ của bạn (bao gồm cả lược đồ và tên máy chủ). Người dùng sẽ nhấp vào liên kết này và trình duyệt sẽ yêu cầu thông tin đăng nhập một lần nữa.

Ví dụ cho 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;
}

Trang lỗi /home/user/errors/401.html:

<!DOCTYPE html>
<p>You're not authorised. <a href="<!--# echo var="scheme" -->://<!--# echo var="host" -->/">Login</a>.</p>

Tôi cũng xin đề nghị sử dụng http_hosttrong 401.htmlthay vì đơn giản host, như cựu cũng cho biết thêm số cổng (trong trường hợp một cổng phi tiêu chuẩn đang được sử dụng)
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;
}

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

2

Dựa trên những gì tôi đọc ở trên, tôi có một giải pháp đơn giản hoạt động trên mọi trình duyệt:

1) trên trang đăng xuất của bạn, bạn gọi ajax để kết thúc đăng nhập của bạn. Đăng nhập cuối của bạn phải chấp nhận người dùng đăng xuất. Khi back end chấp nhận, trình duyệt sẽ xóa người dùng hiện tại và giả sử người dùng "đăng xuất".

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

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

2) Bây giờ khi người dùng quay lại tệp chỉ mục bình thường, nó sẽ cố gắng tự động nhập vào hệ thống với "đăng xuất" của người dùng, vào lần thứ hai này, bạn phải chặn nó bằng cách trả lời bằng 401 để gọi hộp thoại đăng nhập / mật khẩu.

3) Có nhiều cách để làm điều đó, tôi đã tạo hai đầu đăng nhập trở lại, một cách chấp nhận người dùng đăng xuất và một cách không. Trang đăng nhập bình thường của tôi sử dụng trang không chấp nhận, trang đăng xuất của tôi sử dụng trang đăng nhập.


2

Tôi vừa thử nghiệm các tính năng sau trong Chrome (79), Firefox (71) và Edge (44) và nó hoạt động tốt. Nó áp dụng giải pháp kịch bản như những người khác đã lưu ý ở trên.

Chỉ cần thêm liên kết "Đăng xuất" và khi nhấp vào, trả về html sau

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

1

JavaScript này phải hoạt động cho tất cả các trình duyệt phiên bản mới nhất:

//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+'/';
}

1

thêm phần này vào ứng dụng của bạn:

@app.route('/logout')
def logout():
    return ('Logout', 401, {'WWW-Authenticate': 'Basic realm="Login required"'})

tốt hơn để sử dụng lợi nhuận này: return ('Đăng xuất', 401)
Amir Mofakhar

1

chrome://restartvào thanh địa chỉ và chrome, với tất cả các ứng dụng đang chạy trong nền, sẽ khởi động lại và bộ đệm mật khẩu Auth sẽ được xóa.


1

Chỉ để ghi lại, có một Tiêu đề phản hồi HTTP mới được gọi Clear-Site-Data. Nếu trả lời máy chủ của bạn bao gồm một Clear-Site-Data: "cookies"tiêu đề, thì thông tin xác thực (không chỉ cookie) sẽ bị xóa. Tôi đã thử nghiệm nó trên Chrome 77 nhưng cảnh báo này hiển thị trên bảng điều khiển:

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.

Và thông tin xác thực auth không bị xóa, vì vậy điều này không hoạt động (hiện tại) để thực hiện đăng xuất xác thực cơ bản, nhưng có thể trong tương lai sẽ. Không kiểm tra trên các trình duyệt khác.

Người giới thiệu:

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_headftimelear-site-data_cookies


1

Gửi https://invalid_login@hostnamehoạt động tốt ở mọi nơi trừ Safari trên Mac (tốt, không được kiểm tra Edge nhưng cũng hoạt động ở đó).

Đăng xuất không hoạt động trong Safari khi người dùng chọn 'nhớ mật khẩu' trong cửa sổ bật lên Xác thực cơ bản HTTP. Trong trường hợp này, mật khẩu được lưu trữ trong Keychain Access (Finder> Ứng dụng> Tiện ích> Truy cập Keychain (hoặc CMD + SPACE và nhập "Keychain Access")). Gửi https://invalid_login@hostnamekhông ảnh hưởng đến Keychain Access, vì vậy với hộp kiểm này, không thể đăng xuất trên Safari trên Mac. Ít nhất đó là cách nó làm việc cho tôi.

MacOS Mojave (10.14.6), Safari 12.1.2.

Mã dưới đây hoạt động tốt với tôi trong Firefox (73), Chrome (80) và Safari (12). Khi người dùng điều hướng đến trang đăng xuất, mã được thực thi và loại bỏ thông tin đăng nhập.

    //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();

Ngoài ra, vì một số lý do, Safari không lưu thông tin xác thực trong cửa sổ bật lên Xác thực cơ bản HTTP ngay cả khi 'mật khẩu ghi nhớ' được chọn. Các trình duyệt khác làm điều này một cách chính xác.


0
  • sử dụng ID phiên (cookie)
  • làm mất hiệu lực ID phiên trên máy chủ
  • Không chấp nhận người dùng có ID phiên không hợp lệ

Cũng tốt khi cung cấp Xác thực cơ bản dưới dạng lược đồ đăng nhập dự phòng khi cookie không khả dụng.
bobince

0

Tôi đã cập nhật giải pháp của mthoring cho các phiên bản Chrome hiện đại:

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

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

Tôi đã thử sử dụng ở trên theo cách sau.

?php
    ob_start();
    session_start();
    require_once 'dbconnect.php';

    // if session is not set this will redirect to login page
    if( !isset($_SESSION['user']) ) {
        header("Location: index.php");
        exit;
    }
    // select loggedin users detail
    $res=mysql_query("SELECT * FROM users WHERE userId=".$_SESSION['user']);
    $userRow=mysql_fetch_array($res);
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Welcome - <?php echo $userRow['userEmail']; ?></title>
<link rel="stylesheet" href="assets/css/bootstrap.min.css" type="text/css"  />
<link rel="stylesheet" href="style.css" type="text/css" />

    <script src="assets/js/bowser.min.js"></script>
<script>
//function logout(secUrl, redirUrl)
//bowser = require('bowser');
function logout(secUrl, redirUrl) {
alert(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.");
    }
    window.location.assign(redirUrl);
    /*setTimeout(function () {
        window.location.href = redirUrl;
    }, 200);*/
}


function f1()
    {
       alert("f1 called");
       //form validation that recalls the page showing with supplied inputs.    
    }
</script>
</head>
<body>

    <nav class="navbar navbar-default navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="http://www.codingcage.com">Coding Cage</a>
        </div>
        <div id="navbar" class="navbar-collapse collapse">
          <ul class="nav navbar-nav">
            <li class="active"><a href="http://www.codingcage.com/2015/01/user-registration-and-login-script-using-php-mysql.html">Back to Article</a></li>
            <li><a href="http://www.codingcage.com/search/label/jQuery">jQuery</a></li>
            <li><a href="http://www.codingcage.com/search/label/PHP">PHP</a></li>
          </ul>
          <ul class="nav navbar-nav navbar-right">

            <li class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
              <span class="glyphicon glyphicon-user"></span>&nbsp;Hi' <?php echo $userRow['userEmail']; ?>&nbsp;<span class="caret"></span></a>
              <ul class="dropdown-menu">
                <li><a href="logout.php?logout"><span class="glyphicon glyphicon-log-out"></span>&nbsp;Sign Out</a></li>
              </ul>
            </li>
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </nav> 

    <div id="wrapper">

    <div class="container">

        <div class="page-header">
        <h3>Coding Cage - Programming Blog</h3>
        </div>

        <div class="row">
        <div class="col-lg-12" id="div_logout">
        <h1 onclick="logout(window.location.href, 'www.espncricinfo.com')">MichaelA1S1! Click here to see log out functionality upon click inside div</h1>
        </div>
        </div>

    </div>

    </div>

    <script src="assets/jquery-1.11.3-jquery.min.js"></script>
    <script src="assets/js/bootstrap.min.js"></script>


</body>
</html>
<?php ob_end_flush(); ?>

Nhưng nó chỉ chuyển hướng bạn đến vị trí mới. Không đăng xuất.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.