Bagaimana cara keluar pengguna dari situs web menggunakan otentikasi BASIC?


279

Apakah mungkin untuk logout pengguna dari situs web jika dia menggunakan otentikasi dasar?

Sesi pembunuhan tidak cukup, karena, setelah pengguna diautentikasi, setiap permintaan berisi info masuk, sehingga pengguna secara otomatis login di lain waktu ia mengakses situs menggunakan kredensial yang sama.

Satu-satunya solusi sejauh ini adalah menutup browser, tetapi itu tidak dapat diterima dari sudut pandang kegunaan.


1
Hanya penasaran. Mengapa Anda ingin melakukan ini?
DOK

17
Untuk dapat masuk sebagai pengguna yang berbeda.
Marko

16
@DOK - Ini adalah hal peretasan sosial standar: pengguna harus dapat keluar sambil membiarkan peramban terbuka. Misalkan salah satu pengguna Anda mengakses situs di mesin publik? Mereka harus log-off secara eksplisit sehingga pengguna berikutnya tidak dapat mengakses situs seperti mereka.
Keith

@DOK Ada juga masalah yang membuatnya tidak mungkin bagi pengguna untuk keluar dari situs. Server dapat menghapus cookie otorisasi, dan bahkan cookie sesi. Tetapi ketika browser masuk untuk memuat /halaman, mereka akan secara otomatis login lagi.
Ian Boyd

Saya menggunakan metode yang mengirim permintaan palsu untuk keluar, tetapi mengunci pengguna di pelanggan karena ada batasan ketat yang gagal login 3 kali dalam AD. Jadi, sarankan menggunakan metode ini (mengirim permintaan palsu) dengan hati-hati.
Qianchao Pan

Jawaban:


170

Otentikasi dasar tidak dirancang untuk mengelola keluar. Anda dapat melakukannya, tetapi tidak sepenuhnya secara otomatis.

Yang harus Anda lakukan adalah meminta pengguna mengklik tautan logout, dan mengirim tanggapan '401 Tidak Sah', menggunakan ranah yang sama dan pada tingkat folder URL yang sama seperti 401 normal yang Anda kirim meminta login.

Mereka harus diarahkan untuk memasukkan kredensial yang salah selanjutnya, mis. nama pengguna dan kata sandi kosong, dan sebagai tanggapan Anda mengirim kembali halaman "Anda telah berhasil keluar". Kredensial yang salah / kosong kemudian akan menimpa kredensial yang benar sebelumnya.

Singkatnya, skrip logout membalikkan logika skrip login, hanya mengembalikan halaman sukses jika pengguna tidak melewati kredensial yang tepat.

Pertanyaannya adalah apakah kotak kata sandi “jangan masukkan kata sandi” yang agak aneh akan memenuhi penerimaan pengguna. Pengelola kata sandi yang mencoba mengisi kata sandi secara otomatis juga dapat menghalangi di sini.

Sunting untuk menambahkan sebagai tanggapan terhadap komentar: masuk kembali adalah masalah yang sedikit berbeda (kecuali Anda memerlukan logout / login dua langkah jelas). Anda harus menolak (401) upaya pertama untuk mengakses tautan relogin, daripada menerima yang kedua (yang mungkin memiliki nama pengguna / kata sandi lain). Ada beberapa cara Anda bisa melakukan ini. Salah satunya adalah memasukkan nama pengguna saat ini di tautan logout (mis. / Relogin? Nama pengguna), dan menolak ketika kredensial cocok dengan nama pengguna.


2
Saya akan mencoba pendekatan ini. Maksud dari logout (dalam hal ini) adalah untuk memungkinkan pengguna untuk masuk sebagai pengguna yang berbeda, jadi itu adalah solusi yang dapat diterima. Adapun kata sandi pengisian otomatis, terserah pengguna apakah ia akan menggunakannya atau tidak. Terima kasih
Marko

Apakah ini masih satu-satunya jalan? Saya telah melakukan implementasi ASP.Net MVC dan jQuery yang berfungsi, tetapi saya masih tidak senang dengannya: stackoverflow.com/questions/6277919
Keith

@Keith: Masih hanya ini dan jawaban systemPAUSE (yang tidak bekerja di semua browser, tetapi lebih halus daripada pendekatan manual ketika itu bekerja).
bobince

16
W3C sangat aktif pada spesifikasi HTML. Tetapi spec HTTP sedang mendekam. W3C seharusnya memperbaiki masalah ini sekitar dua dekade lalu. Dengan meningkatnya penggunaan layanan REST, metode otentikasi asli yang kuat sangat dibutuhkan saat ini.
Dojo

9
Tampaknya ini tidak berfungsi dengan baik di Chrome 46 menjelajah di localhost. Chrome muncul untuk menjaga kata sandi lama (benar) dan kata sandi baru yang Anda tentukan. Setelah menavigasi ke halaman logout, chrome dengan benar menggunakan kata sandi yang baru SAMPAI SAATNYA MENDAPATKAN A 401 TIDAK DIHORMATI HALAMAN DI SITUS ANDA. Setelah 401 pertama, Chrome kembali ke kata sandi lama (benar). Jadi itu benar-benar tidak menghapus kata sandi sejak awal.
vancan1ty

196

Tambahan untuk jawaban oleh bobince ...

Dengan Ajax Anda dapat memiliki tautan / tombol 'Logout' Anda terhubung ke fungsi Javascript. Minta fungsi ini mengirim XMLHttpRequest dengan nama pengguna dan kata sandi yang buruk. Ini akan mendapatkan 401. Kemudian atur document.location kembali ke halaman pra-login. Dengan cara ini, pengguna tidak akan pernah melihat dialog login tambahan selama logout, atau harus ingat untuk memasukkan kredensial yang buruk.


12
Peretasan bagus, meminta pengguna secara manual memasukkan kredensial buruk mungkin tidak dapat diterima untuk sebagian besar aplikasi web.
BillMan

1
Pastikan saja XMLHttpRequest tidak disetel sebagai tidak sinkron atau Anda mungkin menemukan bahwa pengalihan via akan dilakukan sebelum permintaan logout selesai.
davidjb

5
Anda dapat menggunakan trik yang sama untuk login juga. Dengan begitu Anda dapat menyesuaikan dialog login tanpa harus mengubah metode otentikasi server. Artikel ini memberikan beberapa ide bagus: http://www.peej.co.uk/articles/http-auth-with-html-forms.html
Stijn de Witt

1
@davidjb Karena permintaan sinkron dianggap usang sekarang, solusi alternatif mungkin untuk mengarahkan ulang pengguna dalam panggilan balik permintaan async.
Hayden Schiff

1
David: chrome sekarang mengizinkan ini untuk XHRs, dan saya dapat mengonfirmasi bahwa itu masih berfungsi di kenari chrome. bugs.chromium.org/p/chromium/issues/detail?id=435547
CpnCrunch

192

Minta pengguna mengklik tautan ke https: // log: out@example.com/ . Itu akan menimpa kredensial yang ada dengan yang tidak valid; logout mereka.


19
Mengapa yang ini tidak mendapatkan lebih banyak upvotes? Sepertinya solusi yang sederhana dan berhasil bagi saya. Adakah masalah yang diketahui dengan pendekatan ini?
amoebe

35
Ini tidak lagi berfungsi di Chrome, yang karena alasan keamanan mengabaikan kredensial dalam URL.
Thom

5
Ini Berhasil untuk saya :) Saya menggunakan Versi Chrome 32.0.1700.102
abottoni

6
masalah: menggunakan versi 39.0 chrome, Ketika saya mengklik tautan logout melalui metode ini, Chrome mengingat kredensial login yang buruk, dan meminta kredensial login baru pada setiap pemuatan halaman, sampai saya pergi ke example.com tanpa kredensial login yang ditentukan, untuk hapus memori chrome.
Scott

4
Hai, saya tidak bisa menggunakannya untuk https di Chrome.
thienkhoi tran

67

Anda dapat melakukannya seluruhnya dalam JavaScript:

IE memiliki (untuk waktu yang lama) API standar untuk membersihkan cache Otentikasi Dasar:

document.execCommand("ClearAuthenticationCache")

Harus mengembalikan true ketika berfungsi. Mengembalikan salah, tidak terdefinisi atau meledak di browser lain.

Peramban baru (per Des 2012: Chrome, FireFox, Safari) memiliki perilaku "ajaib". Jika mereka melihat permintaan autentik dasar yang berhasil dengan sembarang nama pengguna palsu lainnya (katakanlah logout) mereka menghapus cache kredensial dan mungkin menyetelnya untuk nama pengguna palsu baru itu, yang perlu Anda pastikan bukan nama pengguna yang valid untuk melihat konten.

Contoh dasar dari itu adalah:

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

Cara "asinkron" untuk melakukan hal di atas adalah dengan melakukan panggilan AJAX menggunakan logoutnama pengguna. Contoh:

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

Anda juga dapat menjadikannya 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
Apakah ini memerlukan penanganan sisi- logoutpengguna khusus untuk nama pengguna dan / atau URL logout?
ulidtko

1
@ Dulidko Tidak, seharusnya tidak - semua penanganan adalah sisi klien. Satu-satunya situasi yang memerlukan penanganan khusus adalah jika pengguna yang dipanggil logoutkebetulan ada dan kebetulan memiliki kata sandi yang dihasilkan. Dalam kasus yang jarang terjadi, ubah ID pengguna menjadi yang tidak ada di sistem Anda.
davidjb

2
Saya menggunakan bookmarklet di atas hari ini dan saya bekerja dengan baik.
David Gleba

Saya menggunakan ini dan itu berhasil untuk Chrome dan FF. Saya hanya perlu melakukan "GET" tambahan pada halaman logout.php saya untuk menghapus $ _SESSION.
urban

2
Bookmarklet juga berfungsi di Edge. Cukup gunakan dengan<a href='javascript:......need*/);'>Logout</a>
Eric

21

Fungsi berikut ini dikonfirmasikan berfungsi untuk Firefox 40, Chrome 44, Opera 31 dan IE 11.
Bowser digunakan untuk deteksi browser, jQuery juga digunakan.

- secUrl adalah url ke area yang dilindungi kata sandi tempat untuk keluar.
- redirUrl adalah url ke area yang tidak dilindungi kata sandi (halaman kesuksesan logout).
- Anda mungkin ingin menambah pengalihan waktu (saat ini 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);
}


ini adalah jawaban paling komprehensif
belidzs

Apakah ada alasan untuk $.ajaxvarian sinkron ( async: false) dan xmlhttpvarian asinkron ( truedalam open())?
Bowi

1
Chrome sekarang menggunakan mesin rendering Blink, sehingga Anda harus mengubah (bowser.gecko)ke (bowser.gecko || bowser.blink).
Bowi

1
Mengapa gecko / blink menggunakan $.ajaxdan menggunakan webkit new XMLHttpRequest? Tidakkah tokek / blink dapat melakukannya XMLHttpRequestdan webkit juga bisa melakukannya $.ajax? Saya bingung.
RemyNL

11

Berikut ini adalah contoh Javascript yang sangat sederhana menggunakan jQuery:

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

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

Pengguna log ini keluar tanpa menunjukkan kotak log-in browser lagi, lalu mengarahkannya ke halaman yang sudah keluar


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

10

Ini tidak mungkin secara langsung dengan Otentikasi-Dasar.

Tidak ada mekanisme dalam spesifikasi HTTP untuk server untuk memberitahu browser untuk berhenti mengirim kredensial yang sudah disajikan pengguna.

Ada "retasan" (lihat jawaban lain) yang biasanya melibatkan penggunaan XMLHttpRequest untuk mengirim permintaan HTTP dengan kredensial yang salah untuk menimpa yang semula disediakan.


12
Dalam teori. Latihan membuktikan sebaliknya sebagaimana dapat dilihat dari jawaban lain.
Stijn de Witt

2
Dan seperti yang Anda juga dapat melihat dari jawaban lain, tidak dengan cara yang dapat diandalkan, konsisten dan gagal-aman!
jplandrain

5

Ini berfungsi untuk 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

Ini sebenarnya cukup sederhana.

Cukup kunjungi yang berikut ini di browser Anda dan gunakan kredensial yang salah: http: // username: password@domainanda.com

Itu harus "mengeluarkan Anda".


1
Tetapi pengguna harus menjadi pengguna NYATA, selain itu saya mendapat "401 Tidak Sah", tetapi dengan menggunakan tombol BACK saya dapat terus bekerja sebagai pengguna yang sebelumnya dicatat. Diuji pada server web Abyss X1 (2.11.1)
user2956477

1
Jawaban rangkap (lihat Matthew Welborn di atas).
Skippy le Grand Gourou

3

Yang Anda butuhkan hanyalah mengarahkan pengguna pada beberapa URL logout dan mengembalikan 401 Unauthorizedkesalahan padanya. Pada halaman kesalahan (yang harus dapat diakses tanpa auth dasar) Anda perlu memberikan tautan lengkap ke halaman rumah Anda (termasuk skema dan nama host). Pengguna akan mengklik tautan ini dan browser akan meminta kredensial lagi.

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

Halaman kesalahan /home/user/errors/401.html:

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

Saya akan lebih menyarankan menggunakan http_hostdi 401.htmlbukan hanya host, sebagai mantan juga menambahkan nomor port (dalam kasus port non-standar yang digunakan)
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

Berdasarkan apa yang saya baca di atas, saya mendapat solusi sederhana yang berfungsi di browser apa pun:

1) pada halaman logout Anda, Anda memanggil ajax ke bagian login Anda Bagian belakang login Anda harus menerima pengguna logout. Setelah bagian belakang menerima, browser menghapus pengguna saat ini dan mengasumsikan pengguna "logout".

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

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

2) Sekarang ketika pengguna kembali ke file indeks normal itu akan mencoba untuk masuk secara otomatis dalam sistem dengan pengguna "logout", pada kali kedua ini Anda harus memblokirnya dengan membalas dengan 401 untuk memunculkan dialog login / kata sandi.

3) Ada banyak cara untuk melakukan itu, saya membuat dua ujung belakang login, satu menerima pengguna logout dan satu lagi tidak. Halaman login normal saya menggunakan yang tidak menerima, halaman logout saya menggunakan yang menerimanya.


2

Saya baru saja menguji yang berikut di Chrome (79), Firefox (71) dan Edge (44) dan berfungsi dengan baik. Itu berlaku solusi skrip seperti yang disebutkan di atas.

Cukup tambahkan tautan "Logout" dan ketika diklik kembalikan html berikut

    <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 ini harus berfungsi untuk semua browser versi terbaru:

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

tambahkan ini ke aplikasi Anda:

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

lebih baik menggunakan pengembalian ini: kembali ('Logout', 401)
Amir Mofakhar

1

ketik chrome://restartbilah alamat dan chrome, dengan semua aplikasi yang berjalan di latar belakang, akan dimulai ulang dan cache kata sandi Auth akan dibersihkan.


1

Sebagai catatan, ada Header HTTP Response baru yang disebut Clear-Site-Data. Jika balasan server Anda menyertakan Clear-Site-Data: "cookies"tajuk, maka kredensial otentikasi (tidak hanya cookie) harus dihapus. Saya mengujinya di Chrome 77 tetapi peringatan ini muncul di konsol:

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.

Dan kredensial auth tidak dihapus, jadi ini tidak berfungsi (untuk saat ini) untuk menerapkan logout auth dasar, tapi mungkin di masa depan akan. Tidak menguji pada browser lain.

Referensi:

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

Mengirim https://invalid_login@hostnameberfungsi dengan baik di mana saja kecuali Safari di Mac (well, tidak mencentang Edge tetapi juga berfungsi di sana).

Logout tidak berfungsi di Safari ketika pengguna memilih 'ingat kata sandi' di sembulan HTTP Otentikasi Dasar. Dalam hal ini kata sandi disimpan di Akses Keychain (Finder> Aplikasi> Utilitas> Akses Keychain (atau CMD + SPACE dan ketik "Akses Keychain")). Mengirim https://invalid_login@hostnametidak mempengaruhi Akses Keychain, jadi dengan kotak centang ini tidak mungkin untuk logout di Safari pada Mac. Setidaknya itu cara kerjanya untuk saya.

MacOS Mojave (10.14.6), Safari 12.1.2.

Kode di bawah ini berfungsi dengan baik untuk saya di Firefox (73), Chrome (80) dan Safari (12). Ketika pengguna menavigasi ke halaman logout kode dieksekusi dan menjatuhkan kredensial.

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

Juga karena suatu alasan Safari tidak menyimpan kredensial dalam sembulan HTTP Otentikasi Dasar bahkan ketika 'ingat kata sandi' dipilih. Browser lain melakukan ini dengan benar.


0
  • gunakan ID sesi (cookie)
  • membatalkan ID sesi di server
  • Jangan terima pengguna dengan ID sesi yang tidak valid

Juga baik untuk menawarkan Otentikasi Dasar sebagai skema masuk cadangan saat cookie tidak tersedia.
bobince

0

Saya memperbarui solusi mthoring untuk versi Chrome modern:

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

Saya mencoba menggunakan di atas dengan cara berikut.

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

Tapi itu hanya mengarahkan Anda ke lokasi baru. Tanpa logout.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.