programing

PHP를 통한 HTTP 인증 로그아웃

shortcode 2022. 11. 4. 22:09
반응형

PHP를 통한 HTTP 인증 로그아웃

HTTP 인증 보호 폴더에서 로그아웃하는 올바른 방법은 무엇입니까?

이 문제를 해결할 수 있는 회피책이 몇 가지 있지만 버그가 발생하거나 특정 상황이나 브라우저가 작동하지 않을 수 있기 때문에 위험할 수 있습니다.그래서 저는 올바르고 깨끗한 해결책을 찾고 있습니다.

Mu. 올바른 방법은 존재하지 않습니다. 브라우저 간에 일관된 방법도 없습니다.

이것은 HTTP 사양(섹션 15.6)에서 발생하는 문제입니다.

기존 HTTP 클라이언트 및 사용자 에이전트는 일반적으로 인증 정보를 무기한 유지합니다.HTTP/1.1.에서는 서버가 클라이언트에게 캐시된 자격 증명을 폐기하도록 지시하는 방법은 제공되지 않습니다.

한편 섹션 10.4.2는 다음과 같이 기술하고 있다.

요청에 이미 인가 credential이 포함되어 있는 경우 401 응답은 해당 credential에 대해 인가가 거부되었음을 나타냅니다.401 응답에 이전 응답과 동일한 과제가 포함되어 있고 사용자 에이전트가 이미1회 이상 인증을 시도한 경우 해당 엔티티에 관련된 진단 정보가 포함될 수 있으므로 해당 엔티티가 응답에 제공된 엔티티를 사용자에게 제시해야 합니다.

, (@Karsten이 말한 것처럼) 로그인 박스를 다시 표시할 수 있지만 브라우저는 당신의 요구를 들어줄 필요가 없습니다.그러므로 이 (잘못된) 기능에 너무 의존하지 마십시오.

Safari에서 잘 작동하는 방법.Firefox 및 Opera에서도 작동하지만 경고와 함께 작동합니다.

Location: http://logout@yourserver.example.com/

그러면 브라우저는 이전 사용자 이름보다 새 사용자 이름으로 URL을 열도록 지시합니다.

간단한 답은 http-authentication에서 확실하게 로그아웃할 수 없다는 것입니다.

답변은 다음과 같습니다.
HTTP-auth(HTTP 사양의 다른 부분과 마찬가지로)는 스테이트리스인 것을 의미합니다.따라서 "로그인" 또는 "로그아웃"되는 것은 이치에 맞지 않는 개념입니다.방법은 각 요구에 (요구임을 "을 할 수 라고 물어보는 입니다.HTTP " " " ( " toinging 、 " inging you you you the the the the the the the the ) 。을 사용하다서버는 각 요청을 새로운 것으로 보고 이전 요청과 관련이 없습니다.

브라우저는 사용자가 처음 401에서 알려주는 자격 증명을 기억하고 이후 요청에 대한 사용자의 명시적 권한 없이 다시 보내도록 선택했습니다.이는 사용자가 기대하는 "로그인/로그아웃" 모델을 사용자에게 제공하려는 시도이지만, 이는 완전히 엉터리입니다.바로 브라우저가 이러한 지속 상태를 시뮬레이션하는 것입니다.웹 서버는 이를 전혀 인식하지 못합니다.

따라서 http-auth 컨텍스트에서 "로그아웃"은 순전히 브라우저에 의해 제공되는 시뮬레이션이므로 서버의 권한 밖입니다.

네, 크러시가 있어요.그러나 RESTfulness(RESTfulness)(고객에게 가치 있는 경우)가 손상되어 신뢰성이 떨어집니다.

사이트 인증에 반드시 로그인/로그아웃 모델이 필요한 경우 가장 좋은 방법은 추적 쿠키를 사용하는 것입니다.이 쿠키에는 어떤 방법으로든 상태가 유지됩니다(mysql, sqlite, platfile 등).이를 위해서는 예를 들어 PHP를 사용하여 모든 요청을 평가해야 합니다.

회피책

Javascript를 사용하여 이 작업을 수행할 수 있습니다.

<html><head>
<script type="text/javascript">
function logout() {
    var xmlhttp;
    if (window.XMLHttpRequest) {
          xmlhttp = new XMLHttpRequest();
    }
    // code for IE
    else if (window.ActiveXObject) {
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    if (window.ActiveXObject) {
      // IE clear HTTP Authentication
      document.execCommand("ClearAuthenticationCache");
      window.location.href='/where/to/redirect';
    } else {
        xmlhttp.open("GET", '/path/that/will/return/200/OK', true, "logout", "logout");
        xmlhttp.send("");
        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4) {window.location.href='/where/to/redirect';}
        }


    }


    return false;
}
</script>
</head>
<body>
<a href="#" onclick="logout();">Log out</a>
</body>
</html>

상기의 조작은 다음과 같습니다.

  • IE의 경우 - 인증 캐시를 지우고 다른 곳으로 리디렉션하기만 하면 됩니다.

  • 다른 브라우저의 경우 - 'logout' 로그인 이름과 비밀번호를 사용하여 XMLHttpRequest를 백그라운드에서 전송합니다.이 요청으로 200 OK를 반환하는 경로로 전송해야 합니다(즉, HTTP 인증은 필요하지 않습니다).

'/where/to/redirect'후 경로가 .'/path/that/will/return/200/OK'.200 OK를 .

회피책(깨끗하고 좋은(또는 코멘트 참조) 솔루션이 아님):

자격 증명을 한 번 비활성화하십시오.

HTTP 인증 로직을 PHP로 이동하려면 적절한 헤더를 전송합니다(로그인하지 않은 경우).

Header('WWW-Authenticate: Basic realm="protected area"');
Header('HTTP/1.0 401 Unauthorized');

또한 입력 구문 분석:

$_SERVER['PHP_AUTH_USER'] // httpauth-user
$_SERVER['PHP_AUTH_PW']   // httpauth-password

그래서 그의 자격증을 한 번 무효로 하는 것은 사소한 일이어야 합니다.

HTTP Basic Auth에서 2단계로 로그아웃

예를 들어 HTTP Basic Auth 렐름 "Password protected" 가 있고 Bob 이 로그인되어 있다고 합시다.로그아웃하려면 2개의 AJAX 요청을 합니다.

  1. 스크립트 /logout_step1에 액세스합니다.임의의 임시 사용자를 .htusers에 추가하고 로그인과 비밀번호로 응답합니다.
  2. 임시 사용자의 로그인비밀번호로 인증된 스크립트 /logout_step2에 액세스합니다.스크립트는 임시 사용자를 삭제하고 응답에 다음 헤더를 추가합니다.WWW-Authenticate: Basic realm="Password protected"

이때 브라우저가 Bob의 자격 증명을 잊어버렸습니다.

그 문제에 대한 저의 해결책은 다음과 같습니다. 때 이 함수는 '아까 말까 합니다.http_digest_parse,$realm ★★★★★★★★★★★★★★★★★」$usershttp://php.net/manual/en/features.http-auth.php 를 참조해 주세요.

session_start();

function LogOut() {
  session_destroy();
  session_unset($_SESSION['session_id']);
  session_unset($_SESSION['logged']);

  header("Location: /", TRUE, 301);   
}

function Login(){

  global $realm;

  if (empty($_SESSION['session_id'])) {
    session_regenerate_id();
    $_SESSION['session_id'] = session_id();
  }

  if (!IsAuthenticated()) {  
    header('HTTP/1.1 401 Unauthorized');
    header('WWW-Authenticate: Digest realm="'.$realm.
   '",qop="auth",nonce="'.$_SESSION['session_id'].'",opaque="'.md5($realm).'"');
    $_SESSION['logged'] = False;
    die('Access denied.');
  }
  $_SESSION['logged'] = True;  
}

function IsAuthenticated(){
  global $realm;
  global $users;


  if  (empty($_SERVER['PHP_AUTH_DIGEST']))
      return False;

  // check PHP_AUTH_DIGEST
  if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) ||
     !isset($users[$data['username']]))
     return False;// invalid username


  $A1 = md5($data['username'] . ':' . $realm . ':' . $users[$data['username']]);
  $A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);

  // Give session id instead of data['nonce']
  $valid_response =   md5($A1.':'.$_SESSION['session_id'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);

  if ($data['response'] != $valid_response)
    return False;

  return True;
}

일반적으로 브라우저가 사용자에게 자격 증명을 요청하고 특정 웹 사이트에 제공하면 더 이상의 프롬프트를 표시하지 않고 자격 증명을 계속 요청합니다.클라이언트 측에서 쿠키를 지울 수 있는 다양한 방법과는 달리 브라우저에 제공된 인증 자격 증명을 잊어버리도록 요청하는 유사한 방법은 모르겠습니다.

은 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★PHP_AUTH_DIGEST ★★★★★★★★★★★★★★★★★」PHP_AUTH_USER 리 and 。PHP_AUTH_PW credentials를 입니다.HTTP/1.1 401 Unauthorized.

function clear_admin_access(){
    header('HTTP/1.1 401 Unauthorized');
    die('Admin access turned off');
}

Trac - 기본적으로는 HTTP 인증도 사용합니다.로그아웃이 작동하지 않으므로 수정할 수 없습니다.

  • 이것은 HTTP 인증 스킴 자체의 문제이며, Trac에서는 올바르게 수정하기 위해 할 수 있는 일이 없습니다.
  • 현재 모든 주요 브라우저에서 작동하는 회피책(JavaScript 또는 기타)은 없습니다.

송신원: http://trac.edgewall.org/ticket/791#comment:103

이 문제는 7년 전에 보고되었으며 HTTP는 스테이트리스입니다.요청이 인증 자격 증명으로 수행되는지 여부를 지정합니다.그러나 이는 클라이언트가 요청을 보내는 문제이지 서버가 요청을 받는 문제가 아닙니다.서버는 요청 URI에 허가가 필요한지 여부만 판단할 수 있습니다.

.htaccess 허가를 리셋해야 했기 때문에 다음 명령을 사용했습니다.

<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
    header('WWW-Authenticate: Basic realm="My Realm"');
    header('HTTP/1.0 401 Unauthorized');
    echo 'Text to send if user hits Cancel button';
    exit;
}
?>

검색처: http://php.net/manual/en/features.http-auth.php

어림짐작하다.

이 페이지에는 다수의 솔루션이 있으며, 하단에 다음과 같은 내용이 기재되어 있습니다.Lynx는 다른 브라우저와 마찬가지로 인증을 클리어하지 않습니다.

설치된 브라우저에서 테스트해 봤는데, 닫히면 각 브라우저는 재입력 시 항상 재인증이 필요한 것 같습니다.

이게 제가 찾던 해결책이 아닐 수도 있는데 이렇게 해결했어요.로그아웃 프로세스에는 2개의 스크립트가 있습니다.

logout.module

<?php
header("Location: http://.@domain.com/log.php");
?>

log.disples

<?php
header("location: https://google.com");
?>

이렇게 하면 경고가 표시되지 않고 세션이 종료됩니다.

AFAIK, htaccess(HTTP 기반) 인증을 사용할 때 "로그아웃" 기능을 구현하는 깔끔한 방법은 없습니다.

이는 이러한 인증이 HTTP 오류 코드 '401'을 사용하여 브라우저에 credential이 필요하다는 것을 알려주기 때문입니다.이 때 브라우저는 사용자에게 상세 정보를 요구합니다.이후 브라우저가 닫힐 때까지 추가 프롬프트 없이 항상 자격 증명을 보냅니다.

코드인 ' 코드입니다.$isLoggedIn「http auth」 「http auth」( 「http auth」)입니다.

"로그아웃" 시 사용자가 실제로 로그아웃되었음을 나타내는 정보를 세션에 저장하기만 하면 됩니다.

function logout()
{
  //$isLoggedIn = false; //This does not work (point of this question)
  $_SESSION['logout'] = true;
}

인증을 확인하는 위치에서 조건을 확장합니다.

function isLoggedIn()
{
  return $isLoggedIn && !$_SESSION['logout'];
}

세션은 http 인증 상태와 어느 정도 연결되어 있기 때문에 사용자가 브라우저를 열어두고 브라우저에서 http 인증이 지속되는 한 로그아웃 상태를 유지합니다.

아마 내가 요점을 놓친 것 같아.

HTTP 인증을 종료하는 가장 확실한 방법은 브라우저와 모든 브라우저 창을 닫는 것입니다.Javascript를 사용하여 브라우저 창을 닫을 수 있지만 모든 브라우저 창을 닫을 수는 없다고 생각합니다.

기본 http 인증에서 로그아웃할 수 없다는 다른 설명도 맞지만 마찬가지로 동작하는 인증을 구현하는 방법도 있습니다.auth_memcookie를 사용하는 것은 명백한 어필입니다.이것을 사용해 기본 HTTP 인증을 실장하는 경우(즉, HTTP 폼이 아닌 로그인에 브라우저 다이얼로그를 사용)는, 유저가 메모리 캐시 세션을 작성한 후에 리다이렉트 하는 PHP 스크립트를 포함한 다른 .htaccess 보호 디렉토리에 인증을 설정하기만 하면 됩니다.

여기 굉장히 복잡한 답이 많이 있어요.특히 로그아웃을 위한 깨끗하고 간단한 수정 방법을 찾았습니다.엣지에서는 아직 테스트하지 않았습니다.로그인한 페이지에 다음과 같은 로그아웃링크가 있습니다.

<a href="https://MyDomainHere.net/logout.html">logout</a>

또한 logout.html 페이지(.htaccess에 의해 보호됨)의 선두에는 다음과 같은 페이지가 갱신됩니다.

<meta http-equiv="Refresh" content="0; url=https://logout:logout@MyDomainHere.net/" />

사이트용으로 캐시된 사용자 이름과 비밀번호를 클리어하기 위해 "logout"이라는 단어를 그대로 사용할 수 있습니다.

처음부터 여러 페이지에 직접 로그인 할 필요가 있는 경우는, 각각의 엔트리 포인트에 대응하는 logout.html 페이지가 필요하게 됩니다.그렇지 않으면 실제 로그인 프롬프트 전에 프로세스에 추가 게이트키퍼 절차를 도입하여 로그아웃을 일원화할 수 있습니다.로그인처에 도달하기 위해서는 구문을 입력해야 합니다.

기사(https://www.hattonwebsolutions.co.uk/articles/how_to_logout_of_http_sessions)에서 솔루션을 요약하고 있습니다만, Ajax 콜과 2x htaccess 파일을 사용하고 있습니다(이 질문에 제시된 바와 같이).Google Chrome에서 작동하는 HTTP 인증(htaccess?)을 로그아웃하는 방법

요컨대, 당신:

  1. 동일한 AuthName에 htaccess 파일이 있는 하위 폴더를 생성하지만 다른 사용자가 필요합니다.
  2. (잘못된 사용자 이름을 가진) 페이지에 Ajax 요청을 보낸 후 로그아웃된 페이지로 타임아웃 리다이렉트를 트리거합니다.

이것에 의해, 로그아웃 폴더에 다른 유저명을 요구하는 세컨더리 팝업이 표시되지 않게 됩니다(사용자가 혼란스러워집니다).내 기사는 Jquery를 사용하지만 이것을 피할 수 있을 것이다.

언급URL : https://stackoverflow.com/questions/449788/http-authentication-logout-via-php

반응형