PHP: HTTP基本身份验证 - 注销登陆

5
我希望设置一个功能,当有人发送“注销”请求时,它会自动跳转到一个页面,显示“注销成功”。如果客户尝试按返回按钮或进入受限区域,它将再次要求HTTP身份验证。
我目前的做法是:
example.com/restricted/index.php:
<?php   
    session_start();

    if(isset($_GET['logout']))
    {
        unset($_SESSION["login"]);
        header("location: ../logout.php");
        exit;
    }

    if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW']) || !isset($_SESSION["login"]))
    {

        header("HTTP/1.0 401 Unauthorized");
        header("WWW-authenticate: Basic realm=\"Tets\"");
        header("Content-type: text/html");
        $_SESSION["login"] = true;
        // Print HTML that a password is required
        exit;
    }
?>
// The rest of the page is then displayed like normal

如果访问example.com/restricted/index.php?logout,则用户成功访问example.com/logout.php。但是,当用户尝试返回时,会发生一些随机的事情,有时它会要求HTTP身份验证两次(???),有时它会在循环中不断地要求身份验证(?),有时它会让我立即返回,好像我从未注销过。
我对会话的工作原理还不太了解,但我的理解是:如果/当人员得到验证,它会在其会话中存储一个名为login的变量,其值为true...如果它每次得到一个带有logout的GET请求,那么它将删除该会话变量并返回到logout.php...为什么当我点击返回到索引时,它会让我回来而不要求身份验证,当session[login]明显没有设置时。
欢迎改进此PHP代码。我知道我不应该使用HTTP Basic并应该整合SQL,但这是一个临时解决方案。
编辑:如果包括具有说明的示例,则将接受具有MySQL的解决方案。我没有MySQL或PHP数据库知识(尚未)。

1
没有会话的情况下,你最好更改基本领域字符串。 - bcosca
仅为临时解决方案而付出如此多的努力,是否值得? - Your Common Sense
@stillstanding 主要问题是何时发送它。如何区分来自已登录用户和来自未登录用户的呼叫 :) - Your Common Sense
3个回答

1

我已经找到了解决方法。

我有两个文件:index.phplogout.php

这是我的 'index.php' 代码:

# CHECK LOGIN.
if (!isset($_SESSION["loged"])) {
    $_SESSION["loged"] = false;
} else {
    if (isset( $_SERVER['PHP_AUTH_USER'] ) && isset($_SERVER['PHP_AUTH_PW'])) {
        if (($_SERVER['PHP_AUTH_USER'] == L_USER) && (md5($_SERVER['PHP_AUTH_PW']) == L_PASS)) {
            $_SESSION["loged"] = true;
        }
    }
}
if ($_SESSION["loged"] === false) {
    header('WWW-Authenticate: Basic realm="Need authorization"');
    header('HTTP/1.0 401 Unauthorized');
    die('<br /><br />
    <div style="text-align:center;">
       <h1 style="color:gray; margin-top:-30px;">Need authorization</h1>
    </div>');
}

这是我的 'logout.php' 代码:

session_start();
$_SESSION["loged"] = false; // We can't use unset($_SESSION) when using HTTP_AUTH.
session_destroy();

1

一个初步的想法供您参考:

<?php   
  session_start();

  if( isset( $_GET['logout'] ) )
  {
    session_destroy();
    header('Location: ../logout.php');
    exit;
  }

  if( !isset( $_SESSION['login'] ) )
  {
    if( !isset( $_SERVER['PHP_AUTH_USER'] ) || !isset( $_SERVER['PHP_AUTH_PW'] ) )
    {
      header("HTTP/1.0 401 Unauthorized");
      header("WWW-authenticate: Basic realm=\"Tets\"");
      header("Content-type: text/html");
      // Print HTML that a password is required
      exit;
    }
    else
    {
      // Validate the $_SERVER['PHP_AUTH_USER'] & $_SERVER['PHP_AUTH_PW']
      if( $_SERVER['PHP_AUTH_USER']!='TheUsername'
          || $_SERVER['PHP_AUTH_PW']!='ThePassword' )
      {
        // Invalid: 401 Error & Exit
        header("HTTP/1.0 401 Unauthorized");
        header("WWW-authenticate: Basic realm=\"Tets\"");
        header("Content-type: text/html");
        // Print HTML that a username or password is not valid
        exit;
      }
      else
      {
        // Valid
        $_SESSION['login']=true;
      }
    }
  }
?>
// The rest of the page is then displayed like normal

如果这只是一个临时解决方案,而你只需要一个用户名/密码组合,那么可以像这样做:if( $_SERVER['PHP_AUTH_USER']!='TheUsername' || $_SERVER['PHP_AUTH_PW']!='ThePassword' ) { /* 401 Error & Exit */ } else { $_SESSION['login']=true }。就我个人而言,我以前没有使用过PHP_AUTH_USER/PHP_AUTH_PW,我倾向于使用一个表单通过$_GET或$_POST传递他们的用户名和密码 - 更简单。 - Luke Stevenson
@Brian 把登录名和密码保存在数据库中? - Your Common Sense
@Col 如所述,我没有数据库。 @Lucanos,不,这只是一个集合。 - ParoX
@Brian:我在回复中提供的代码已经合并到我的答案中了。 - Luke Stevenson
@Brian:没问题,非常感谢。很高兴继续提供帮助。你需要使用多少个用户名/密码?我知道你没有使用数据库,但我可能能想出一种处理方法。 - Luke Stevenson
显示剩余2条评论

0

您可以使用元标记http-equiv="refresh",并设置非常短的响应时间(例如content="1")。这个刷新将清除任何$_POST

if ( !isset($_SERVER['PHP_AUTH_USER']) || $_SERVER['PHP_AUTH_USER']!='myusername' || $_SERVER['PHP_AUTH_PW']!='mypassword' || isset($_POST['logout']) ) {
    header('WWW-Authenticate: Basic realm="My protected area"');
    header('HTTP/1.0 401 Unauthorized');
    echo '<html><head><title>401 Unauthorized</title><meta http-equiv="refresh" content="1"></head><body><h1>401 Unauthorized</h1><p>You are not allowed to see this page. Reload the page to try again.</p></body></html>';
    exit();
} 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接