BASIC 인증을 사용하여 웹 사이트에서 사용자를 로그 아웃하는 방법은 무엇입니까?


279

기본 인증을 사용하는 경우 웹 사이트에서 사용자를 로그 아웃 할 수 있습니까?

사용자가 인증되면 각 요청에 로그인 정보가 포함되므로 다음 번에 동일한 자격 증명을 사용하여 사이트에 액세스 할 때 사용자가 자동으로 로그인되므로 세션 종료가 충분하지 않습니다.

지금까지 유일한 해결책은 브라우저를 닫는 것이지만 사용성 측면에서는 받아 들일 수 없습니다.


1
그냥 궁금해서 왜 이러고 싶니?
DOK

17
다른 사용자로 로그인 할 수 있습니다.
Marko

16
@DOK-표준 소셜 해킹입니다. 사용자는 브라우저를 연 상태에서 로그 아웃 할 수 있어야합니다. 사용자 중 한 사람이 공용 컴퓨터의 사이트에 액세스한다고 가정 해보십시오. 다음 사용자가 사이트에 액세스 할 수 없도록 명시 적으로 로그 오프해야합니다.
Keith

@DOK 또한 사용자가 사이트에서 로그 아웃 할 수 없다는 문제가 있습니다. 서버는 인증 쿠키 및 세션 쿠키를 지울 수 있습니다. 그러나 브라우저가 /페이지 를로드 하면 자동으로 다시 로그인됩니다.
Ian Boyd

로그 아웃하기 위해 가짜 요청을 보내는 방법을 사용하고 있지만 AD에서 로그인이 3 번 실패했다는 제한이 있기 때문에 고객의 사용자를 잠급니다. 따라서이 방법을 사용하여 (가짜 요청 보내기)주의하십시오.
Qianchao Pan

답변:


170

기본 인증은 로그 아웃을 관리하도록 설계되지 않았습니다. 당신은 그것을 할 수 있지만 완전히 자동으로 할 수는 없습니다.

사용자가 로그 아웃 링크를 클릭하고 로그인을 요청하는 일반 401과 동일한 영역과 동일한 URL 폴더 레벨을 사용하여 응답으로 '401 Unauthorized'를 보내도록해야합니다.

다음에 잘못된 자격 증명을 입력하도록 지시해야합니다 (예 : 빈 사용자 이름과 비밀번호를 입력하면 "로그 아웃되었습니다"페이지가 나타납니다. 잘못된 / 빈 자격 증명은 이전의 올바른 자격 증명을 덮어 씁니다.

간단히 말해, 로그 아웃 스크립트는 로그인 스크립트의 논리를 반전시키고 사용자 올바른 자격 증명을 전달 하지 않은 경우에만 성공 페이지를 반환합니다 .

문제는 다소 호기심 많은 "비밀번호를 입력하지 마십시오"비밀번호 상자가 사용자의 승인을 충족시키는 지 여부입니다. 암호를 자동으로 채우려 고하는 암호 관리자도 여기에 들어갈 수 있습니다.

댓글에 대한 응답으로 추가하려면 편집 : 재 로그인은 약간 다른 문제입니다 (두 단계의 로그 아웃 / 로그인이 분명하지 않은 경우). 재 로그인 링크에 대한 첫 번째 시도는 두 번째 시도 (다른 사용자 이름 / 암호가있을 수 있음)를 수락하는 것보다 먼저 거부해야합니다 (401). 이를 수행 할 수있는 몇 가지 방법이 있습니다. 하나는 로그 아웃 링크에 현재 사용자 이름 (예 : / relogin? username)을 포함하고 자격 증명이 사용자 이름과 일치하면 거부합니다.


2
이 방법을 시도해 보겠습니다. 로그 아웃 시점 (이 경우)은 사용자가 다른 사용자로 로그인 할 수 있도록하는 것이므로 완벽하게 수용 가능한 솔루션입니다. 자동 완성 비밀번호는 비밀번호 사용 여부에 따라 사용자가 결정합니다. 감사합니다
Marko

이것이 여전히 유일한 방법입니까? 작동하는 ASP.Net MVC 및 jQuery 구현을 수행했지만 여전히 만족스럽지 않습니다. stackoverflow.com/questions/6277919
Keith

@ Keith : 여전히 이것과 systemPAUSE의 대답 (모든 브라우저에서 작동하지는 않지만 작동 할 때 수동 접근법보다 부드럽습니다).
bobince 2016 년

16
W3C는 HTML 사양에서 매우 활발합니다. 그러나 HTTP 사양은 어려워지고 있습니다. W3C는 약 20 년 전에이 문제를 해결했을 것입니다. REST 서비스 사용이 증가함에 따라 강력한 기본 인증 방법이 필요합니다.
Dojo

9
localhost를 탐색하는 Chrome 46에서는 제대로 작동하지 않는 것 같습니다. Chrome이 이전 (올바른) 비밀번호와 지정한 새 비밀번호를 모두 유지하는 것으로 보입니다. 로그 아웃 페이지로 이동 한 후 chrome은 사이트의 페이지에서 승인되지 않은 A401을 찾을 때까지 새 비밀번호를 올바르게 사용합니다. 처음 401 후에 Chrome은 이전 (올바른) 비밀번호로 되돌아갑니다. 그래서 처음에는 암호를 삭제하지 않았습니다.
vancan1ty

196

bobince의 답변에 추가 ...

Ajax를 사용하면 '로그 아웃'링크 / 버튼을 Javascript 기능에 연결할 수 있습니다. 이 함수가 잘못된 사용자 이름과 비밀번호로 XMLHttpRequest를 보내도록하십시오. 그러면 401이 다시 나타납니다. 그런 다음 document.location을 사전 로그인 페이지로 다시 설정하십시오. 이런 식으로 사용자는 로그 아웃하는 동안 추가 로그인 대화 상자를 볼 수 없으며 잘못된 자격 증명을 입력해야합니다.


12
사용자가 잘못된 자격 증명을 수동으로 입력하도록하는 것은 좋은 웹 해킹 일 수 있습니다.
BillMan

1
XMLHttpRequest가 비동기로 설정되어 있지 않은지 확인하거나 로그 아웃 요청이 완료되기 전에 경로 재 지정이 수행 될 수 있습니다.
davidjb

5
동일한 트릭을 사용하여 로그인 할 수도 있습니다. 이렇게하면 서버의 인증 방법을 변경하지 않고도 로그인 대화 상자를 사용자 정의 할 수 있습니다. 이 문서에서는 좋은 아이디어를 제공합니다 http://www.peej.co.uk/articles/http-auth-with-html-forms.html
스테인 드 위트

1
@davidjb 이제 동기 요청이 더 이상 사용되지 않는 것으로 간주되기 때문에 대체 솔루션은 비동기 요청의 콜백에서 사용자를 리디렉션하는 것일 수 있습니다.
헤이든 쉬프

1
David : 크롬은 이제 XHR에 이것을 허용하며, 크롬 카나리아에서 여전히 작동하고 있음을 확인할 수 있습니다. bugs.chromium.org/p/chromium/issues/detail?id=435547
CpnCrunch 17시 49 분

192

사용자에게 https : // log : out@example.com/ 링크를 클릭하도록합니다 . 기존 자격 증명을 유효하지 않은 자격 증명으로 덮어 씁니다. 로그 아웃


19
왜 이것이 더 많은 투표를 얻지 못합니까? 나에게 간단하고 작동하는 솔루션 인 것 같습니다. 이 접근 방식에 알려진 문제가 있습니까?
amoebe

35
Chrome에서는 더 이상 작동하지 않으며, 보안상의 이유로 URL의 자격 증명은 무시합니다.
Thom

5
이것은 나를 위해 일했다 :) 나는 크롬 버전 32.0.1700.102를 사용하고
abottoni

6
문제 : 크롬 39.0 버전을 사용하는 경우이 방법을 통해 로그 아웃 링크를 클릭하면 Chrome은 잘못된 로그인 자격 증명을 기억하고 지정된 로그인 자격 증명없이 example.com으로 이동할 때까지 모든 페이지로드에서 새로운 로그인 자격 증명을 묻는 메시지를 표시 합니다. 크롬의 기억을 지우십시오.
Scott

4
안녕하세요, Chrome에서 https로 사용할 수 없습니다.
thienkhoi tran

67

당신은 완전히 JavaScript로 할 수 있습니다 :

IE는 기본 인증 캐시를 지우는 표준 API를 오랫동안 가지고 있습니다.

document.execCommand("ClearAuthenticationCache")

작동하면 true를 반환해야합니다. 다른 브라우저에서 false, undefined 또는 blow-up을 반환합니다.

새로운 브라우저 (2012 년 12 월 현재 : 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@')

위의 "비동기"방법은 logout사용자 이름을 사용하여 AJAX 호출을 수행하는 것 입니다. 예:

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

북마크로 만들 수도 있습니다.

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
오늘 위의 북마크를 사용했는데 잘 작동합니다.
David Gleba

나는 이것을 사용했고 Chrome과 FF에서 효과가있었습니다. $ _SESSION을 지우려면 logout.php 페이지에서 추가 "GET"만하면됩니다.
도시

2
북마크릿도 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변형이 비동기 ( truein open()) 인 이유가 있습니까?
Bowi

1
Chrome은 이제 렌더링 엔진 깜박임을 사용하므로로 변경 (bowser.gecko)해야 (bowser.gecko || bowser.blink)합니다.
Bowi

1
gecko / blink $.ajax와 webkit 은 왜 사용 new XMLHttpRequest합니까? gecko / blink가 할 수 XMLHttpRequest있고 웹킷도 할 수 없어야 $.ajax합니까? 혼란 스러워요.
RemyNL

11

다음은 jQuery를 사용하는 매우 간단한 Javascript 예제입니다.

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 : // username : password@yourdomain.com

"로그 아웃"해야합니다.


1
그러나 사용자는 REAL 사용자 여야합니다. 그렇지 않으면 "401 Unauthorized"가 표시되지만 BACK 단추를 사용하면 이전에 기록한 사용자로 작업을 계속할 수 있습니다. Abyss 웹 서버 X1 (2.11.1)에서 테스트
user2956477

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

위에서 읽은 내용을 기반으로 모든 브라우저에서 작동하는 간단한 솔루션을 얻었습니다.

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) 여러 가지 방법으로 로그 아웃 사용자를 허용하는 로그인 백엔드와 그렇지 않은 로그인 백엔드를 생성했습니다. 내 일반 로그인 페이지는 수락하지 않는 로그인 페이지를 사용하고, 내 로그 아웃 페이지는 승인 된 로그인 페이지를 사용합니다.


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"'})

return ( 'Logout', 401)
Amir Mofakhar

1

chrome://restart주소 표시 줄에 입력 하면 크롬이 백그라운드에서 실행되는 모든 앱과 함께 다시 시작되고 인증 비밀번호 캐시가 정리됩니다.


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는 Mac의 Safari를 제외한 모든 곳에서 잘 작동합니다. Edge는 선택하지 않았지만 작동합니다.

사용자가 HTTP 기본 인증 팝업에서 '암호 기억'을 선택하면 Safari에서 로그 아웃이 작동하지 않습니다. 이 경우 암호는 키 체인 액세스 (파인더> 응용 프로그램> 유틸리티> 키 체인 액세스 (또는 CMD + SPACE 및 "키 체인 액세스"유형))에 저장됩니다. 전송 https://invalid_login@hostname은 키 체인 접근에 영향을 미치지 않으므로이 확인란을 사용하면 Mac의 Safari에서 로그 아웃 할 수 없습니다. 적어도 그것이 나를 위해 작동하는 방법입니다.

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를 무효화
  • 유효하지 않은 세션 ID를 가진 사용자를 허용하지 마십시오

쿠키를 사용할 수없는 경우에 대한 백업 로그인 체계로 기본 인증을 제공하는 것도 좋습니다.
bobince

0

최신 Chrome 버전에 대한 mthoring의 솔루션을 업데이트했습니다.

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.