سؤال

ما هو الصحيح طريقة تسجيل الخروج من مصادقة HTTP المحمية المجلد ؟

هناك الحلول التي يمكن أن تحقق هذا ، ولكنها يمكن أن تكون خطيرة لأنها يمكن أن تكون عربات التي تجرها الدواب أو لا تعمل في بعض الحالات / المتصفحات.هذا هو السبب أنا أبحث عن الصحيح و تنظيف الحل.

هل كانت مفيدة؟

المحلول

مو. لا الطريق الصحيح موجود, ولا حتى واحدة متسقة في جميع المتصفحات.

هذه هي المشكلة التي تأتي من مواصفات HTTP (القسم 15.6):

القائمة HTTP عملاء و وكلاء المستخدم عادة الاحتفاظ المصادقة المعلومات إلى أجل غير مسمى.HTTP/1.1.لا توفر وسيلة خادم لتوجيه العملاء إلى تجاهل هذه بيانات الاعتماد المخزنة مؤقتا.

من ناحية أخرى, قسم 10.4.2 يقول:

إذا كان الطلب المدرجة بالفعل أوراق التفويض ، ثم 401 رد يشير إلى أن الإذن قد تم رفض تلك وثائق التفويض.إذا 401 رد يحتوي على نفس التحدي كما قبل الاستجابة وكيل المستخدم قد حاول بالفعل المصادقة على الأقل مرة واحدة ، ثم يجب أن يكون المستخدم قدم الكيان التي أعطيت في الاستجابة ، حيث أن هذا الكيان قد وتضمين معلومات التشخيص.

وبعبارة أخرى ، كنت قد تكون قادرة على أن تظهر مربع تسجيل الدخول مرة أخرى (كما @كارستن يقول) ، ولكن المتصفح لا يجب أن نحترم طلبك لذا لا تعتمد على هذا (mis)ميزة أكثر من اللازم.

نصائح أخرى

والطريقة التي تعمل بشكل جيد في سفاري. يعمل أيضا في فايرفوكس وأوبرا، ولكن مع تحذير.

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

وهذا يقول المتصفح لفتح URL مع اسم مستخدم جديد، تجاوز سابقتها.

الجواب بسيط هو أنه لا يمكنك موثوق تسجيل الخروج من http المصادقة.

الجواب طويلة:
Http-المصادقة (مثل بقية HTTP المواصفات) من المفترض أن يكون عديم الجنسية.حيث يجري "تسجيل الدخول" أو "تسجيل الخروج" ليس المفهوم أن من المنطقي.أفضل طريقة لمعرفة ذلك هو أن نسأل عن كل طلب HTTP (وتذكر تحميل الصفحة عادة طلبات متعددة), "هل مسموح لك أن تفعل ما أنت تطلب?".الخادم يرى كل طلب جديد و لا علاقة لها بأي الطلبات السابقة.

المتصفحات اختارت أن تذكر بيانات الاعتماد كنت أقول لهم في أول 401 ، وإعادة إرسالها دون إذن صريح المستخدم على الطلبات اللاحقة.هذه محاولة إعطاء المستخدم "تسجيل الدخول/تسجيل الخروج" نموذج يتوقعون, لكنه محض الهمجية.انها المتصفح هذا هو محاكاة هذا استمرار الدولة.خادم الويب هو يجهل تماما من ذلك.

إذن "تسجيل الخروج" في سياق http-المصادقة هو محض محاكاة المقدمة من قبل المتصفح, و حتى خارج سلطة الخادم.

نعم ، هناك kludges.لكنها كسر راحة-نيس (إذا كان هذا هو قيمة لك) وهم لا يمكن الاعتماد عليها.

إذا كنت على الاطلاق تتطلب تسجيل الدخول/تسجيل الخروج نموذج على موقع الويب الخاص بك المصادقة أفضل رهان هو تتبع الكوكيز ، مع استمرار الدولة المخزنة على الخادم بطريقة (mysql, سكليتي, flatfile ، إلخ).وهذا يتطلب من جميع الطلبات التي يتم تقييمها ، على سبيل المثال ، مع PHP.

الحل

يمكنك القيام بذلك باستخدام جافا سكريبت:

<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 - فقط واضحة مصادقة ذاكرة التخزين المؤقت وإعادة توجيه في مكان ما

  • عن المتصفحات الأخرى - إرسال مدعوم من وراء الكواليس مع "تسجيل الخروج" اسم تسجيل الدخول وكلمة المرور.ونحن بحاجة لإرسالها إلى بعض الطريق الذي سيعود 200 موافق على هذا الطلب (أييجب أن لا تتطلب مصادقة HTTP).

محل '/where/to/redirect' مع بعض طريق إعادة توجيه إلى بعد تسجيل الخروج و استبدال '/path/that/will/return/200/OK' مع بعض المسار على موقع الويب الخاص بك سوف يعود 200 موافق.

الحل (غير نظيفة ، لطيفة (أو حتى العمل!انظر التعليقات) الحل):

تعطيل أوراق اعتماده وقت واحد.

يمكنك نقل مصادقة 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 الأساسية المصادقة في خطوتين

دعونا نقول لدي HTTP الأساسية المصادقة عالم اسمه "كلمة السر المحمية" و " بوب " هو تسجيل الدخول.تسجيل الخروج أجعل 2 طلبات اياكس:

  1. الوصول إلى البرنامج النصي /logout_step1.وتضيف عشوائي مؤقت المستخدم .htusers ويستجيب مع تسجيل الدخول وكلمة المرور.
  2. الوصول إلى البرنامج النصي /logout_step2 مع مصادقة مؤقتة المستخدم تسجيل الدخول وكلمة المرور.السيناريو حذف مستخدم مؤقت و يضيف هذا الرأس على الرد: WWW-Authenticate: Basic realm="Password protected"

عند هذه النقطة المتصفح نسيت بوب التفويض.

وبلدي حل لهذه المشكلة هو ما يلي: يمكنك العثور على وظيفة http_digest_parse، $realm و$users في المثال الثاني من هذه الصفحة: http://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;
}

وعادة، مرة واحدة في المتصفح وطلب المستخدم وثائق التفويض وتوفيره لهم موقع على شبكة الإنترنت خاص، وسوف تواصل القيام بذلك دون مزيد من المطالبة. على عكس العديد من الطرق التي يمكن مسح ملفات تعريف الارتباط على جانب العميل، وأنا لا أعرف من وسيلة مماثلة ليطلب من المتصفح لتنس أوراق اعتماد المصادقة الموردة لها.

تراك - افتراضيا - يستخدم مصادقة HTTP كذلك.الخروج لا يعمل و لا يمكن أن تكون ثابتة:

  • هذه قضية مع مصادقة HTTP المخطط نفسه ، وليس هناك شيء يمكننا القيام به في تراك لإصلاحه بشكل صحيح.
  • لا يوجد حاليا أي حل (جافا سكريبت أو غيرها) الذي يعمل مع جميع المتصفحات الرئيسية.

من: http://trac.edgewall.org/ticket/791#comment:103

يبدو أنه لا يوجد العامل في الإجابة على السؤال أن هذه المسألة قد ذكرت قبل سبع سنوات و يجعل الشعور بالكمال:HTTP هو عديمي الجنسية.إما طلب فعل مع مصادقة بيانات الاعتماد أو لا.ولكن هذا الأمر من العميل إرسال طلب وليس الخادم الحصول عليها.الخادم يمكن أن أقول فقط إذا طلب URI يحتاج إلى ترخيص أم لا.

أنا في حاجة إلى إعادة تعيين .هتكس إذن إذا كنت تستخدم هذا:

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

يذهب الرقم.

عددا من الحلول الموجودة على هذه الصفحة و ذلك حتى تلاحظ في الأسفل:الوشق, لا واضح مصادقة مثل المتصفحات الأخرى ;)

لقد اختبرت ذلك على المتصفحات المثبتة وبمجرد إغلاق كل متصفح يبدو باستمرار يتطلب reauth على العودة.

وهذا قد يكون ليس الحل الذي كان ينظر لكنني حلها من هذا القبيل. لقد 2 البرامج النصية لعملية الخروج.

وlogout.php

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

وlog.php

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

ويتم إنهاء بهذه الطريقة أنا لا تحصل على تحذير وجلسة بلدي

وAFAIK، وليس هناك طريقة نظيفة لتنفيذ "خروج" وظيفة عند استخدام هتكس (أي HTTP على أساس) المصادقة.

وذلك لأن مثل هذه المصادقة يستخدم رمز الخطأ HTTP '401' لنقول للمتصفح المطلوبة وثائق التفويض، وعند هذه النقطة المستعرض يطالب المستخدم للحصول على التفاصيل. ومنذ ذلك الحين، حتى يتم إغلاق المستعرض، وسوف ترسل دائما وثائق التفويض دون مزيد من المطالبة.

والحل الأمثل وجدت حتى الآن هو (وهو نوع من شبه رمز، و$isLoggedIn هو متغير الزائفة للمصادقة HTTP):

وفي وقت "خروج" مجرد تخزين بعض المعلومات إلى الدورة قائلا يتم تسجيل الواقع أن مستخدم.

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

في المكان الذي كنت تحقق للمصادقة I توسيع الشرط:

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

ووالدورة مرتبطة إلى حد ما في حالة مصادقة HTTP حتى يبقى المستخدم تسجيل الخروج طالما أنه يحافظ على متصفح مفتوح، وطالما استمرت مصادقة HTTP في المتصفح.

وربما أنا في عداد المفقودين نقطة.

والطريقة الأكثر موثوقية وجدتها لإنهاء مصادقة HTTP هي لإغلاق المتصفح وجميع نوافذ المتصفح. يمكنك إغلاق نافذة المتصفح باستخدام جافا سكريبت لكنني لا أعتقد أنه يمكنك إغلاق كل نوافذ المتصفح.

والطريقة الوحيدة الفعالة لقد وجدت للقضاء على PHP_AUTH_DIGEST أو PHP_AUTH_USER وPHP_AUTH_PW أوراق اعتماد لاستدعاء HTTP/1.1 401 Unauthorized الرأس.

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

بينما الصحيح في القول أن من المستحيل الخروج من مصادقة http الأساسية هناك طرق تنفيذ المصادقة التي تتصرف وبالمثل.واحد واضح appeoach هو استخدام auth_memcookie.إذا كنت تريد حقا أن تنفيذ مصادقة HTTP الأساسية (أياستخدام متصفح الحوارات للتسجيل في trather من HTTP شكل) باستخدام هذا - مجرد مجموعة مصادقة منفصل .هتكس المحمية الدليل الذي يحتوي السيناريو PHP الذي الموجهات حيث te المستخدم جاء بعد createing على memcache الدورة.

وهناك الكثير من عظيم - مجمع - الأجوبة هنا. في حالتي خاصة وجدت حلا نظيفة وبسيطة للخروج. ليس لدي حتى الآن لاختبار في الحافة. على صفحتي بأنني مسجلا ل، لقد وضعت وصلة الخروج مشابهة لهذه:

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

وفي الرأس تلك الصفحة logout.html (وهو محمي أيضا هتكس) لدي صفحة تنعش مشابهة لهذه:

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

وأين أنت من شأنه أن يترك عبارة "خروج" في مكان لمسح اسم المستخدم وكلمة المرور المخزنة مؤقتا للموقع.

وأنا لن أعترف أنه إذا صفحات متعددة تحتاج إلى أن تكون قادرة على أن تكون مسجلا مباشرة في لمن البداية، ستحتاج كل تلك نقاط الدخول الخاصة الصفحة logout.html المقابلة. وإلا هل يمكن مركزة الخروج عن طريق إدخال خطوة البواب إضافية في عملية قبل موجه تسجيل الدخول الفعلي، مما يتطلب دخول العبارة للوصول إلى المقصد من تسجيل الدخول.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top