Как выйти из веб-сайта с использованием аутентификации BASIC?

Можно ли вывести пользователя с веб-сайта, если он использует базовую аутентификацию?

Недостаточно сеанса Killing, поскольку после аутентификации пользователя каждый запрос содержит информацию для входа в систему, поэтому пользователь автоматически регистрируется в следующий раз, когда он/она получает доступ к сайту с использованием тех же учетных данных.

Единственное решение - закрыть браузер, но это не приемлемо с точки зрения удобства использования.

Ответ 1

Базовая проверка подлинности не была предназначена для управления протоколированием. Вы можете сделать это, но не полностью автоматически.

То, что вам нужно сделать, - это нажать на ссылку для выхода из системы и отправить сообщение "401 Unauthorized в ответ", используя ту же область и на том же уровне URL-адресов, что и обычный 401, который вы отправляете, запрашивая логин.

Они должны быть направлены для последующего ввода неправильных учетных данных, например. пустое имя пользователя и пароль, и в ответ вы отправляете страницу "Вы успешно вышли из системы". Неправильные/пустые учетные данные затем перезапишут предыдущие правильные учетные данные.

Короче говоря, выход из системы script инвертирует логику входа script, только возвращает страницу успеха, если пользователь не передает правильные учетные данные.

Вопрос в том, будет ли несколько любопытный пароль "не вводить пароль", будет соответствовать принятию пользователем. Менеджеры паролей, которые пытаются автоматически заполнить пароль, также могут попасть сюда.

Отредактируйте для добавления в ответ на комментарий: повторный вход - это немного другая проблема (если вам не требуется двухэтапный выход из системы/логин). Вы должны отклонить (401) первую попытку доступа к ссылке relogin, чем принять вторую (которая предположительно имеет другое имя пользователя/пароль). Есть несколько способов сделать это. Можно было бы указать текущее имя пользователя в ссылке выхода (например, имя пользователя /relogin?) И отклонить, когда учетные данные совпадут с именем пользователя.

Ответ 2

В дополнение к ответу bobince...

С помощью Ajax у вас может быть ссылка/кнопка "Выход", связанная с функцией Javascript. Попросите эту функцию отправить XMLHttpRequest с плохим именем пользователя и паролем. Это должно вернуть 401. Затем верните документ .location на страницу предварительного входа. Таким образом, пользователь никогда не увидит дополнительное диалоговое окно входа во время выхода из системы и не должен забывать о том, чтобы ввести плохие учетные данные.

Ответ 3

Попросите пользователя щелкнуть ссылку на https://log:[email protected]/. Это приведет к перезаписи существующих учетных данных с недопустимыми; вывешивая их.

Ответ 4

Вы можете сделать это полностью в JavaScript:

IE имеет (в течение длительного времени) стандартный API для очистки базового кэша аутентификации:

document.execCommand("ClearAuthenticationCache")

Должен возвращать true, когда он работает. Возвращает либо false, undefined, либо взрывается в других браузерах.

Новые браузеры (по состоянию на декабрь 2012 года: Chrome, FireFox, Safari) имеют "магическое" поведение. Если они видят успешный базовый запрос auth с любым фиктивным другим именем пользователя (пусть logout), они очищают кеш учетных данных и, возможно, устанавливают его для этого нового имени пользователя с фикцией, что вам необходимо убедиться, что это не действительное имя пользователя для просмотра содержание.

Основной пример:

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

"Асинхронный" способ сделать это - это сделать вызов 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 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*/)

Вы также можете сделать это букмарклет:

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

Ответ 5

Подтверждена следующая функция для Firefox 40, Chrome 44, Opera 31 и IE 11.
Bowser используется для обнаружения браузера, также используется jQuery.

- secUrl - это URL-адрес защищенной паролем области, из которой выходить.
- redirUrl - это URL-адрес области, не защищенной паролем (страница успеха выхода из системы).
- вы можете увеличить таймер переадресации (в настоящее время 200 мс).

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

Ответ 6

Это невозможно напрямую с помощью Basic-Authentication.

В спецификации HTTP нет механизма для того, чтобы сервер сообщал браузеру о прекращении отправки учетных данных, которые пользователь уже представил.

Есть "хаки" (см. другие ответы), обычно включающие использование XMLHttpRequest для отправки HTTP-запроса с неправильными учетными данными для перезаписывания исходных данных.

Ответ 7

Вот очень простой пример Javascript с использованием jQuery:

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

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

Этот журнал выйдет из системы, не показывая ему окно входа в браузер снова, а затем перенаправит его на страницу с завершенным протоколом

Ответ 8

Это на самом деле довольно просто.

Просто зайдите в свой браузер и используйте неправильные учетные данные: http://имя пользователя: [email protected]

Это должно "вывести вас".

Ответ 9

Это работает для 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"); 
      });
  });          

Ответ 10

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

Ответ 11

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

Ответ 12

добавьте это в ваше приложение:

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

Ответ 13

Все, что вам нужно, - перенаправить пользователя на некоторый URL выхода и вернуть на него ошибку 401 Unauthorized. На странице ошибок (которая должна быть доступна без базового auth) вам необходимо предоставить полную ссылку на вашу домашнюю страницу (включая схему и имя хоста). Пользователь нажмет эту ссылку, и браузер снова попросит ввести учетные данные.

Пример для 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>

Ответ 14

Основываясь на том, что я прочитал выше, я получил простое решение, которое работает в любом браузере:

1) на странице выхода из системы вы вызываете ajax на ваш логин. Ваш конец входа в систему должен принять пользователя для выхода из системы. После того, как задняя часть будет принята, браузер очистит текущего пользователя и примет пользователя "выход из системы".

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

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

2) Теперь, когда пользователь вернется в нормальный индексный файл, он попытается автоматически ввести систему в систему с "выходом пользователя" пользователя, во второй раз вы должны заблокировать его с помощью ответа 401, чтобы вызвать логин/пароль диалоговое окно.

3) Есть много способов сделать это, я создал два конца входа в систему, один из которых принимает пользователя выхода из системы, а другой - нет. Моя обычная страница входа использует ту, которая не принимает, моя страница выхода из системы использует тот, который ее принимает.

Ответ 15

  • используйте идентификатор сеанса (cookie)
  • аннулировать идентификатор сеанса на сервере
  • Не принимать пользователей с недопустимыми идентификаторами сеанса.

Ответ 16

Этот 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 = /*@[email protected]*/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 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:[email protected]'+Host+'/';
}

Ответ 17

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

Ответ 18

Я обновил решение 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);
}

Ответ 19

наберите chrome://restart в адресной строке, и chrome со всеми приложениями, работающими в фоновом режиме, перезапустится и очистит кеш паролей аутентификации.