当前位置:  开发笔记 > 编程语言 > 正文

通过PHP进行HTTP身份验证注销

如何解决《通过PHP进行HTTP身份验证注销》经验,为你挑选了7个好方法。

注销HTTP身份验证保护文件夹的正确方法是什么?

有一些解决方法可以实现这一点,但它们具有潜在的危险性,因为它们可能是错误的,或者在某些情况/浏览器中不起作用.这就是为什么我正在寻找正确和干净的解决方案.



1> Piskvor cc-b..:

亩.没有正确的方法,甚至没有一个跨浏览器一致的方式.

这是来自HTTP规范的问题(第15.6节):

现有的HTTP客户端和用户代理通常会无限期地保留身份验证信息.HTTP/1.1.没有提供服务器指示客户端丢弃这些缓存凭据的方法.

另一方面,第10.4.2节说:

如果请求已包含授权凭据,则401响应表示已拒绝授权这些凭据.如果401响应包含与先前响应相同的挑战,并且用户代理已经尝试过至少一次认证,则应该向用户呈现响应中给出的实体,因为该实体可能包括相关的诊断信息.

换句话说,您可以再次显示登录框(如@Karsten所说),但浏览器不必遵守您的请求 - 因此不要过多依赖此(错误)功能.


这是RFC中的一个错误.W3C懒得修理.好难过.

2> Kornel..:

在Safari中很好地工作的方法.也适用于Firefox和Opera,但有警告.

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

这告诉浏览器使用新用户名打开URL,覆盖前一个用户名.


根据RFC 3986(URI:通用语法)第3.2.1节.(用户信息)不推荐使用`user:password @ host`.仅使用`http:// logout @ yourserver.example.com /`并不适用于大多数情况.
注意:重新登录后使用相对路径提交表单可能会失败(使用logout提示登录),因为地址仍然是[logout@yourserver.example.com/path](http:// logout @ yourserver.example.com/path/)而不是[yourserver.example.com/path/](http://yourserver.example.com/path/)

3> Jonathan Han..:

简单的答案是您无法可靠地注销http身份验证.

答案很长:
Http-auth(与HTTP规范的其余部分一样)意味着无状态.因此,"登录"或"退出"并不是一个有意义的概念.更好的方法是询问每个HTTP请求(并记住页面加载通常是多个请求),"你被允许做你要求的吗?".服务器将每个请求视为新请求,与先前的任何请求无关.

浏览器选择记住您在第一个401上告诉他们的凭据,并在没有用户对后续请求的明确许可的情况下重新发送它们.这是为了向用户提供他们期望的"登录/注销"模型,但它纯粹是一种kludge.这是模拟这种状态持久性的浏览器.Web服务器完全没有意识到它.

因此,在http-auth的上下文中"注销"纯粹是由浏览器提供的模拟,因此在服务器的权限之外.

是的,有kludges.但是他们打破了RESTful-ness(如果这对你有价值的话)并且它们是不可靠的.

如果您绝对需要登录/注销模型进行站点身份验证,最好的选择是跟踪cookie,状态的持久性以某种方式存储在服务器上(mysql,sqlite,flatfile等).这将要求评估所有请求,例如,使用PHP.



4> 小智..:

解决方法

你可以使用Javascript来做到这一点:





Log out


上面做的是:

对于IE - 只需清除身份验证缓存并重定向到某个地方

对于其他浏览器 - 使用'logout'登录名和密码在幕后发送XMLHttpRequest.我们需要将它发送到某个路径,该路径将向该请求返回200 OK(即它不应该要求HTTP身份验证).

'/where/to/redirect'在注销后替换为某些路径以重定向到并替换'/path/that/will/return/200/OK'为您的站点上将返回200 OK的某个路径.


这是以另一个用户身份登录的一种解决方法.但这实际上是有效的,值得更多的信任.
我认为这是最好的答案.如[this](http://stackoverflow.com/a/14329930/2433501)中所述回答类似问题,随机化密码可能有一些优势.
这就是我想要的 - 在所有浏览器中都没有问题.保持我正确继承的"注销"页面.我不一定想使用JS(可能是非理性的),但其他答案都有跨浏览器问题,这很完美.
这不起作用,因为它被解释.在Chrome 40和Firefox 35中测试过.

5> Karsten..:

解决方法(不是干净,漂亮(甚至工作!请参阅注释)解决方案):

一次禁用他的凭据.

您可以通过发送相应的标头(如果未登录)将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

因此,一次禁用他的凭据应该是微不足道的.


此解决方案的问题在于:您让IE知道凭据不正常.它显示带有空字段的登录对话框(不显示存储在密码管理器中的值).但是当您单击取消并刷新页面时,它会发送存储的凭据,从而再次登录.

6> Pie86..:

我对此问题的解决方案如下.你可以找到的功能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;
}



7> Vlad GURDIGA..:

从HTTP Basic Auth注销,分两步进行

假设我有一个名为"密码保护"的HTTP Basic Auth领域,并且Bob已登录.要注销,我发出2个AJAX请求:

    访问脚本/ logout_step1.它会向.htusers添加一个随机临时用户,并使用其登录名和密码进行响应.

    访问脚本/ logout_step2 使用临时用户的登录名和密码进行身份验证.该脚本删除临时用户并在响应中添加此标头:WWW-Authenticate: Basic realm="Password protected"

此时浏览器忘记了Bob的凭据.

推荐阅读
yzh148448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有