วิธีการออกจากระบบผู้ใช้จากเว็บไซต์โดยใช้การรับรองความถูกต้องเบื้องต้น?


279

เป็นไปได้หรือไม่ที่จะล็อกเอาต์ผู้ใช้จากเว็บไซต์ถ้าเขาใช้การพิสูจน์ตัวตนพื้นฐาน?

เซสชันการฆ่าไม่เพียงพอเนื่องจากเมื่อผู้ใช้ได้รับการรับรองความถูกต้องแล้วแต่ละคำขอจะมีข้อมูลการเข้าสู่ระบบดังนั้นผู้ใช้จะเข้าสู่ระบบโดยอัตโนมัติในครั้งต่อไปที่เขา / เธอเข้าถึงเว็บไซต์โดยใช้ข้อมูลรับรองเดียวกัน

ทางออกเดียวคือปิดเบราว์เซอร์ แต่ไม่ยอมรับจากมุมมองการใช้งาน


1
แค่สงสัย. ทำไมคุณถึงต้องการทำเช่นนี้?
DOK

17
เพื่อให้สามารถเข้าสู่ระบบในฐานะผู้ใช้อื่น
Marko

16
@DOK - เป็นสิ่งที่แฮ็คทางสังคมมาตรฐาน: ผู้ใช้ควรจะออกจากระบบในขณะที่เปิดเบราว์เซอร์ สมมติว่าหนึ่งในผู้ใช้ของคุณเข้าถึงเว็บไซต์บนเครื่องสาธารณะหรือไม่ พวกเขาจำเป็นต้องออกจากระบบอย่างชัดเจนเพื่อให้ผู้ใช้รายต่อไปไม่สามารถเข้าใช้งานเว็บไซต์ได้
Keith

@DOK นอกจากนี้ยังมีปัญหาที่ทำให้ผู้ใช้ไม่สามารถออกจากระบบได้ เซิร์ฟเวอร์สามารถล้างคุกกี้การอนุญาตและแม้แต่คุกกี้เซสชัน แต่เมื่อเบราว์เซอร์ไปโหลด/หน้าเว็บพวกเขาจะเข้าสู่ระบบอีกครั้งโดยอัตโนมัติ
Ian Boyd

ฉันใช้วิธีที่ส่งคำขอปลอมเพื่อออกจากระบบ แต่จะล็อคผู้ใช้ในลูกค้าเนื่องจากมีข้อ จำกัด ที่ทำให้การเข้าสู่ระบบล้มเหลว 3 ครั้งในโฆษณา ดังนั้นแนะนำให้ใช้วิธีนี้ (ส่งคำขอปลอม) ด้วยความระมัดระวัง
Qianchao Pan

คำตอบ:


170

การรับรองความถูกต้องพื้นฐานไม่ได้ออกแบบมาเพื่อจัดการการออกจากระบบ คุณสามารถทำได้ แต่ไม่ได้ทำโดยอัตโนมัติอย่างสมบูรณ์

สิ่งที่คุณต้องทำคือให้ผู้ใช้คลิกที่ลิงค์ออกจากระบบและส่ง '401 Unauthorized' เพื่อตอบกลับโดยใช้ realm เดียวกันและที่ระดับโฟลเดอร์ URL เดียวกันกับ 401 ปกติที่คุณส่งการร้องขอ

พวกเขาจะต้องถูกนำไปใส่ข้อมูลประจำตัวที่ไม่ถูกต้องต่อไปเช่น ชื่อผู้ใช้และรหัสผ่านที่ว่างเปล่าและในการตอบกลับคุณส่งหน้า“ คุณออกจากระบบเรียบร้อยแล้ว” ข้อมูลประจำตัวที่ไม่ถูกต้อง / ว่างเปล่าจะเขียนทับข้อมูลประจำตัวที่ถูกต้องก่อนหน้านี้

กล่าวโดยสรุปสคริปต์การออกจากระบบจะย้อนกลับตรรกะของสคริปต์การเข้าสู่ระบบเพียงส่งคืนหน้าความสำเร็จหากผู้ใช้ไม่ผ่านข้อมูลรับรองที่ถูกต้อง

คำถามคือช่องรหัสผ่าน“ อย่าป้อนรหัสผ่านของคุณ” ที่น่าสงสัยจะตอบสนองการยอมรับของผู้ใช้หรือไม่ ผู้จัดการรหัสผ่านที่พยายามป้อนรหัสผ่านอัตโนมัติสามารถเข้าไปที่นี่ได้เช่นกัน

แก้ไขเพื่อเพิ่มในการตอบสนองต่อความคิดเห็น: การเข้าสู่ระบบใหม่เป็นปัญหาที่แตกต่างกันเล็กน้อย (เว้นแต่ว่าคุณต้องการออกจากระบบ / เข้าสู่ระบบสองขั้นตอนอย่างชัดเจน) คุณต้องปฏิเสธ (401) ความพยายามครั้งแรกในการเข้าถึงลิงก์ relogin แทนที่จะยอมรับที่สอง (ซึ่งมีชื่อผู้ใช้ / รหัสผ่านที่แตกต่างกัน) มีสองสามวิธีที่คุณสามารถทำได้ หนึ่งจะรวมถึงชื่อผู้ใช้ปัจจุบันในลิงค์ออกจากระบบ (เช่น / relogin? ชื่อผู้ใช้) และปฏิเสธเมื่อข้อมูลประจำตัวตรงกับชื่อผู้ใช้


2
ฉันจะลองวิธีนี้ จุดออกจากระบบ (ในกรณีนี้) คือการให้ผู้ใช้เข้าสู่ระบบในฐานะผู้ใช้ที่แตกต่างกันดังนั้นจึงเป็นทางออกที่ยอมรับได้อย่างสมบูรณ์ สำหรับรหัสผ่านอัตโนมัตินั้นขึ้นอยู่กับผู้ใช้ว่าเขาจะใช้หรือไม่ ขอบคุณ
Marko

นี่เป็นวิธีเดียวหรือไม่ ฉันได้ทำการติดตั้ง ASP.Net MVC และ jQuery แล้ว แต่ฉันก็ยังไม่พอใจกับมัน: stackoverflow.com/questions/6277919
Keith

@Keith: ยังมีเพียงคำตอบนี้และคำตอบของ systemPAUSE (ซึ่งไม่สามารถใช้ได้กับเบราว์เซอร์ทั้งหมด แต่จะราบรื่นกว่าวิธีการด้วยตนเองเมื่อใช้งานได้)
bobince

16
W3C ใช้งานได้ดีกับสเป็ค HTML แต่สเป็ค HTTP ก็อ่อนกำลังลง W3C ควรแก้ไขปัญหานี้เมื่อประมาณสองทศวรรษที่แล้ว ด้วยการใช้บริการ REST ที่เพิ่มขึ้นวิธีการรับรองความถูกต้องแบบเนทีฟที่จำเป็นสำหรับวันนี้
Dojo

9
สิ่งนี้ดูเหมือนว่าจะไม่ทำงานอย่างถูกต้องในการเรียกดู Chrome บน localhost Chrome ดูเหมือนจะเก็บรหัสผ่านเก่า (ถูกต้อง) และรหัสผ่านใหม่ที่คุณระบุ หลังจากการนำทางไปยังหน้าออกจากระบบโครเมี่ยมจะใช้รหัสผ่านใหม่อย่างถูกต้องจนกว่าจะเปิดใช้งาน 401 ที่ไม่ได้รับอนุญาตบนหน้าหนึ่งบนเว็บไซต์ของคุณ หลังจาก 401 แรก Chrome จะเปลี่ยนกลับเป็นรหัสผ่านเก่า (ถูกต้อง) ดังนั้นจึงไม่ได้ลบรหัสผ่านในครั้งแรกที่ดูเหมือนว่า
vancan1ty

196

นอกเหนือจากคำตอบโดย bobince ...

ด้วย Ajax คุณสามารถใช้ลิงก์ / ปุ่มออกจากระบบไปยังฟังก์ชัน Javascript ได้ ให้ฟังก์ชันนี้ส่ง XMLHttpRequest ด้วยชื่อผู้ใช้และรหัสผ่านที่ไม่ถูกต้อง สิ่งนี้ควรจะได้รับกลับมา 401 จากนั้นตั้งค่า document.location กลับไปที่หน้าก่อนเข้าสู่ระบบ ด้วยวิธีนี้ผู้ใช้จะไม่เห็นกล่องโต้ตอบการเข้าสู่ระบบเพิ่มเติมระหว่างการออกจากระบบและไม่ต้องจำไว้ว่าต้องใส่ข้อมูลประจำตัวที่ไม่ถูกต้อง


12
แฮ็คที่ดีการให้ผู้ใช้ป้อนข้อมูลประจำตัวด้วยตนเองอาจไม่เป็นที่ยอมรับสำหรับ webapps ส่วนใหญ่
BillMan

1
เพียงตรวจสอบให้แน่ใจว่า XMLHttpRequest ไม่ได้ถูกตั้งค่าเป็นแบบอะซิงโครนัสหรือคุณอาจพบว่าการเปลี่ยนเส้นทางผ่านจะเกิดขึ้นก่อนที่คำขอออกจากระบบจะเสร็จสมบูรณ์
davidjb

5
คุณสามารถใช้เคล็ดลับเดียวกันนี้ในการเข้าสู่ระบบได้เช่นกัน ด้วยวิธีนี้คุณสามารถกำหนดไดอะล็อกล็อกอินโดยไม่ต้องเปลี่ยนวิธีการพิสูจน์ตัวตนของเซิร์ฟเวอร์ บทความนี้ให้ความคิดที่ดี: http://www.peej.co.uk/articles/http-auth-with-html-forms.html
Stijn de Witt

1
@davidjb เนื่องจากคำร้องขอแบบซิงโครนัสถูกพิจารณาว่าเลิกใช้แล้วในขณะนี้โซลูชันทางเลือกอาจจะเปลี่ยนเส้นทางผู้ใช้ในการติดต่อกลับของคำขอ async
Hayden Schiff

1
เดวิด: ตอนนี้โครเมี่ยมอนุญาตให้ใช้กับ XHR ได้แล้วและฉันสามารถยืนยันได้ว่ามันยังใช้งานได้ในนกขมิ้นโครเมี่ยม bugs.chromium.org/p/chromium/issues/detail?id=435547
CpnCrunch

192

มีผู้ใช้คลิกที่ลิงก์เพื่อhttps: // บันทึก: out@example.com/ ซึ่งจะเขียนทับข้อมูลประจำตัวที่มีอยู่ด้วยข้อมูลที่ไม่ถูกต้อง ออกจากระบบ


19
ทำไมอันนี้ไม่ได้รับ upvotes มากขึ้น? ดูเหมือนว่าเป็นวิธีที่ง่ายและทำงานให้ฉัน มีปัญหาใด ๆ ที่ทราบเกี่ยวกับวิธีนี้หรือไม่?
อะมีบา

35
สิ่งนี้จะไม่ทำงานใน Chrome อีกต่อไปซึ่งด้วยเหตุผลด้านความปลอดภัยจะไม่สนใจข้อมูลรับรองใน URL
Thom

5
สิ่งนี้ได้ผลสำหรับฉัน :) ฉันใช้ Chrome รุ่น 32.0.1700.102
abottoni

6
ปัญหา: ใช้รุ่น 39.0 ของโครเมี่ยม, เมื่อฉันคลิกลิงค์ล็อกเอาต์ผ่านทางวิธีนี้ Chrome จะจำข้อมูลการล็อกอินไม่ดีและแจ้งข้อมูลประจำตัวสำหรับเข้าสู่ระบบใหม่ในการโหลดหน้าทุกจนกว่าฉันจะไปexample.comโดยไม่ต้องเข้าสู่ระบบข้อมูลประจำตัวที่ระบุใด ๆ ที่จะ ล้างหน่วยความจำของ chrome
สกอตต์

4
สวัสดีฉันไม่สามารถใช้กับ https บน Chrome ได้
thienkhoi tran

67

คุณสามารถทำได้ทั้งหมดใน JavaScript:

IE มี API มาตรฐาน (เป็นเวลานาน) สำหรับล้างแคชการตรวจสอบสิทธิ์พื้นฐาน:

document.execCommand("ClearAuthenticationCache")

ควรกลับมาจริงเมื่อมันทำงาน ส่งคืน false, undefined หรือระเบิดในเบราว์เซอร์อื่น

เบราว์เซอร์ใหม่ (ณ เดือนธันวาคม 2555: Chrome, FireFox, Safari) มีพฤติกรรม "วิเศษ" หากพวกเขาเห็นคำขอรับรองความถูกต้องเบื้องต้นที่ประสบความสำเร็จด้วยชื่อผู้ใช้ปลอมอื่น ๆ (สมมติว่าlogout) พวกเขาล้างแคชข้อมูลประจำตัวและอาจตั้งเป็นชื่อผู้ใช้ปลอมใหม่ซึ่งคุณต้องแน่ใจว่าไม่ใช่ชื่อผู้ใช้ที่ถูกต้องสำหรับการดูเนื้อหา

ตัวอย่างพื้นฐานของนั่นคือ:

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

วิธี "แบบอะซิงโครนัส" ในการทำข้างต้นคือการโทร AJAX โดยใช้logoutชื่อผู้ใช้ ตัวอย่าง:

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

คุณสามารถทำให้มันเป็น 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
สิ่งนี้ต้องใช้การจัดการด้านเซิร์ฟเวอร์พิเศษของlogoutชื่อผู้ใช้และ / หรือ URL ออกจากระบบหรือไม่?
ulidtko

1
@ulidtko ไม่ไม่ควร - การจัดการทั้งหมดเป็นฝั่งไคลเอ็นต์ สถานการณ์เดียวที่จะต้องมีการจัดการพิเศษคือถ้าผู้ใช้ที่เรียกว่าlogoutเกิดขึ้นมีอยู่และเกิดขึ้นกับรหัสผ่านที่สร้างขึ้น ในกรณีที่แทบจะเป็นไปไม่ได้ให้เปลี่ยน ID ผู้ใช้เป็นรหัสที่ไม่มีอยู่ในระบบของคุณ
davidjb

2
ฉันใช้ bookmarklet ด้านบนวันนี้และฉันทำงานได้ดี
David Gleba

ฉันใช้มันและมันก็ใช้ได้กับ Chrome และ FF ฉันต้องทำ "GET" พิเศษในหน้า logout.php เพื่อล้าง $ _SESSION
เมือง

2
bookmarklet ทำงานบน Edge เช่นกัน ใช้กับ<a href='javascript:......need*/);'>Logout</a>
Eric

21

ฟังก์ชั่นต่อไปนี้ได้รับการยืนยันว่าใช้งานได้กับ Firefox 40, Chrome 44, Opera 31 และ IE 11
Bowserใช้สำหรับการตรวจหาเบราว์เซอร์และยังใช้ jQuery

- secUrl คือ url ไปยังพื้นที่ที่มีการป้องกันด้วยรหัสผ่านที่จะออกจากระบบ
- redirUrl เป็น URL ไปยังพื้นที่ที่ไม่มีการป้องกันด้วยรหัสผ่าน (หน้าความสำเร็จในการออกจากระบบ)
- คุณอาจต้องการเพิ่มตัวจับเวลาการเปลี่ยนเส้นทาง (ปัจจุบัน 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);
}


นี่เป็นคำตอบที่ครอบคลุมที่สุด
belidzs

มีเหตุผลใดบ้างสำหรับ$.ajaxตัวแปรที่กำลังซิงโครนัส ( async: false) และxmlhttpตัวแปรเป็นอะซิงโครนัส ( trueในopen())?
Bowi

1
โครเมี่ยมตอนนี้ใช้เครื่องมือการแสดงผลกะพริบตาเพื่อให้คุณมีการเปลี่ยนแปลงไป(bowser.gecko) (bowser.gecko || bowser.blink)
Bowi

1
ทำไมตุ๊กแก / กะพริบใช้$.ajaxและ webkit ใช้new XMLHttpRequest? ไม่ควรตุ๊กแก / กระพริบตาสามารถทำได้XMLHttpRequestและ webkit ก็สามารถทำได้เช่น$.ajaxกัน? ฉันสับสน
RemyNL

11

นี่เป็นตัวอย่าง Javascript ที่ง่ายมากโดยใช้ jQuery:

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

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

ผู้ใช้ออกจากระบบนี้โดยไม่แสดงช่องลงชื่อเข้าใช้เบราว์เซอร์อีกครั้งจากนั้นเปลี่ยนเส้นทางเขาไปยังหน้าออกจากระบบ


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

10

สิ่งนี้ไม่สามารถทำได้โดยตรงกับการพิสูจน์ตัวตนพื้นฐาน

ไม่มีกลไกในข้อกำหนด HTTP สำหรับเซิร์ฟเวอร์เพื่อบอกเบราว์เซอร์ว่าให้หยุดส่งข้อมูลรับรองที่ผู้ใช้นำเสนอไปแล้ว

มี "แฮ็ก" (ดูคำตอบอื่น ๆ ) โดยทั่วไปเกี่ยวข้องกับการใช้ XMLHttpRequest เพื่อส่งคำขอ HTTP ที่มีข้อมูลประจำตัวที่ไม่ถูกต้องเพื่อเขียนทับคำสั่งที่ให้มา


12
ในทางทฤษฎี การปฏิบัติพิสูจน์เป็นอย่างอื่นที่สามารถเห็นได้จากคำตอบอื่น ๆ
Stijn de Witt

2
และอย่างที่คุณเห็นจากคำตอบอื่น ๆ ไม่ใช่ในวิธีที่เชื่อถือได้สอดคล้องและไม่ปลอดภัย!
jplandrain

5

สิ่งนี้ใช้ได้กับ 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

จริงๆแล้วมันค่อนข้างง่าย

เพียงไปที่เบราว์เซอร์ของคุณและใช้ข้อมูลประจำตัวที่ไม่ถูกต้อง: http: // ชื่อผู้ใช้: รหัสผ่าน @ yourourdomain.com

ที่ควร "คุณออกจากระบบ"


1
แต่ผู้ใช้จะต้องเป็นผู้ใช้จริงและฉันยังได้รับ "401 Unauthorized" แต่ใช้ปุ่ม BACK ฉันสามารถทำงานต่อได้ในฐานะผู้ใช้ที่บันทึกไว้ก่อนหน้านี้ ทดสอบบนเว็บเซิร์ฟเวอร์ Abyss X1 (2.11.1)
2956477

1
คำตอบที่ซ้ำกัน (ดูด้านบนของ Matthew Welborn)
Skippy le Grand Gourou

3

สิ่งที่คุณต้องมีคือเปลี่ยนเส้นทางผู้ใช้ใน URL ออกจากระบบบางส่วนและส่งคืน401 Unauthorizedข้อผิดพลาด ในหน้าข้อผิดพลาด (ซึ่งจะต้องสามารถเข้าถึงได้โดยไม่ต้องมีการตรวจสอบขั้นพื้นฐาน) คุณจะต้องให้ลิงก์แบบเต็มไปยังหน้าแรกของคุณ (รวมถึงแบบแผนและชื่อโฮสต์) ผู้ใช้จะคลิกที่ลิงค์นี้และเบราว์เซอร์จะขอข้อมูลประจำตัวอีกครั้ง

ตัวอย่างสำหรับ 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;
}

หน้าข้อผิดพลาด/home/user/errors/401.html:

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

ฉันยังขอแนะนำให้ใช้http_hostใน401.htmlแทนที่จะhostเป็นอดีตนอกจากนี้ยังเพิ่มจำนวนพอร์ต (ในกรณีที่พอร์ตที่ไม่ได้มาตรฐานจะถูกใช้)
เอมิล 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

จากสิ่งที่ฉันอ่านข้างต้นฉันได้วิธีง่ายๆที่ทำงานบนเบราว์เซอร์ใด ๆ :

1) ในหน้าล็อกเอาต์ที่คุณเรียกว่า ajax เพื่อเข้าสู่ระบบ back end ปลายด้านหลังเข้าสู่ระบบของคุณจะต้องยอมรับผู้ใช้ออกจากระบบ เมื่อสิ้นสุดด้านหลังยอมรับเบราว์เซอร์ล้างผู้ใช้ปัจจุบันและถือว่าผู้ใช้ "ออกจากระบบ"

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

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

2) ตอนนี้เมื่อผู้ใช้กลับไปที่ไฟล์ดัชนีปกติมันจะพยายามป้อนอัตโนมัติในระบบด้วยผู้ใช้ "ออกจากระบบ" ในครั้งที่สองนี้คุณจะต้องปิดกั้นโดยตอบกลับด้วย 401 เพื่อเรียกใช้กล่องโต้ตอบเข้าสู่ระบบ / รหัสผ่าน

3) มีหลายวิธีในการทำเช่นนั้นฉันสร้างการลงชื่อเข้าใช้สองหลังสิ้นสุดหนึ่งวิธีที่ยอมรับผู้ใช้ออกจากระบบและอีกวิธีหนึ่งที่ไม่ได้ทำ หน้าเข้าสู่ระบบปกติของฉันใช้หน้าเว็บที่ไม่ยอมรับหน้าออกจากระบบของฉันใช้หน้าเว็บที่ยอมรับ


2

ฉันเพิ่งทดสอบสิ่งต่อไปนี้ใน Chrome (79), Firefox (71) และ Edge (44) และใช้งานได้ดี มันใช้โซลูชันสคริปต์ตามที่คนอื่น ๆ ระบุไว้ข้างต้น

เพียงเพิ่มลิงค์ "ออกจากระบบ" และเมื่อคลิกแล้วให้ส่งคืน 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>

1

JavaScript นี้ต้องใช้งานได้กับเบราว์เซอร์เวอร์ชันล่าสุดทั้งหมด:

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

เพิ่มไปยังแอปพลิเคชันของคุณ:

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

ดีกว่าที่จะใช้การส่งคืนนี้: ส่งคืน ('ออกจากระบบ', 401)
Amir Mofakhar

1

พิมพ์chrome://restartในแถบที่อยู่และโครเมี่ยมที่มีแอพทั้งหมดที่ทำงานในพื้นหลังจะเริ่มต้นใหม่และแคชรหัสผ่าน Auth จะถูกล้าง


1

เพียงแค่สำหรับบันทึกมีใหม่ตอบสนองของ HTTP Clear-Site-Dataส่วนหัวที่เรียกว่า หากการตอบกลับของเซิร์ฟเวอร์ของคุณมีClear-Site-Data: "cookies"ส่วนหัวดังนั้นควรลบข้อมูลรับรองการตรวจสอบสิทธิ์ (ไม่เฉพาะคุกกี้) ฉันทดสอบใน Chrome 77 แต่คำเตือนนี้แสดงบนคอนโซล:

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.

และข้อมูลรับรองความถูกต้องจะไม่ถูกลบดังนั้นจึงไม่สามารถใช้งานได้ (ในตอนนี้) เพื่อใช้งานการรับรองความถูกต้องเบื้องต้น แต่อาจจะเกิดขึ้นในอนาคต ไม่ได้ทดสอบกับเบราว์เซอร์อื่น

อ้างอิง:

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


1

การส่งhttps://invalid_login@hostnameทำงานได้ดีทุกที่ยกเว้น Safari บน Mac (เช่นกันไม่ได้ตรวจสอบ Edge แต่ควรทำงานที่นั่นด้วย)

การออกจากระบบไม่ทำงานใน Safari เมื่อผู้ใช้เลือก 'จดจำรหัสผ่าน' ในป๊อปอัปการตรวจสอบสิทธิ์พื้นฐาน HTTP ในกรณีนี้รหัสผ่านจะถูกเก็บไว้ใน Keychain Access (Finder> แอปพลิเคชั่น> ยูทิลิตี้> Keychain Access (หรือ CMD + SPACE และพิมพ์ "Keychain Access")) การส่งhttps://invalid_login@hostnameไม่ส่งผลกระทบต่อการเข้าถึง Keychain ดังนั้นด้วยช่องทำเครื่องหมายนี้จึงไม่สามารถออกจากระบบ Safari บน Mac อย่างน้อยมันเป็นวิธีการทำงานสำหรับฉัน

MacOS Mojave (10.14.6), Safari 12.1.2

รหัสด้านล่างใช้ได้ดีสำหรับฉันใน Firefox (73), Chrome (80) และ Safari (12) เมื่อผู้ใช้นำทางไปยังหน้าออกจากระบบรหัสจะถูกดำเนินการและลดข้อมูลประจำตัว

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

นอกจากนี้ด้วยเหตุผลบางอย่าง Safari ไม่บันทึกข้อมูลรับรองในป๊อปอัปการตรวจสอบสิทธิ์พื้นฐาน HTTP แม้ว่าจะมีการเลือก 'จดจำรหัสผ่าน' ก็ตาม เบราว์เซอร์อื่นทำสิ่งนี้อย่างถูกต้อง


0
  • ใช้ ID เซสชัน (คุกกี้)
  • ทำให้รหัสเซสชันเป็นโมฆะบนเซิร์ฟเวอร์
  • อย่ายอมรับผู้ใช้ที่มี ID เซสชันที่ไม่ถูกต้อง

นอกจากนี้ยังเป็นการดีที่จะเสนอการรับรองความถูกต้องเบื้องต้นเป็นรูปแบบการเข้าสู่ระบบสำรองสำหรับเมื่อไม่มีคุกกี้
bobince

0

ฉันอัปเดตโซลูชันของ mthoring สำหรับ 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);
}

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

ฉันลองใช้ข้างต้นด้วยวิธีดังต่อไปนี้

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

แต่จะเปลี่ยนเส้นทางคุณไปยังตำแหน่งใหม่เท่านั้น ไม่มีการออกจากระบบ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.