正确设置注销 link

Setting up a logout link properly

目前正在使用 Sign-Up/Login 系统与 PHP 一起工作。情况是这样的:

我的第一页名为 "signup.php",用于注册和登录。提交表单后,您将被重定向到名为 "diary.php" 的第二页。单击提交按钮后,将在 "users" 数据库中分别使用您的 ID 创建一个会话。如果没有 diary.php,则会出现注销 link。 如果您已注册或登录并且现在正在查看 diary.php,您将无法查看 signup.php 页面,除非您按下注销。一旦您按下注销,您将被重定向到 signup.php 页面,但在 $_GET 数组中有一个注销变量。

<a href='signup.php?logout=1'>Logout</a>

我正在使用这个注销变量来检查 $_GET 数组中是否存在 "logout" 键,它会破坏会话并将我重定向回 signup.php 页面。

问题来了。假设我注册了一个新帐户,然后注销了。一旦我注销,GET 中就会有一个 "logout" 键,对吧? (销毁会话)。如果我尝试注册另一个帐户,它实际上会为我注册(在数据库上),但它会自动为我注销,因为我的 link 中有注销密钥,也因为没有会话(如果没有会话,我的代码中有几行会自动将您带回 signup.php)。

我希望这足以让大家明白。我将留下我的两个页面的代码供您检查。谢谢!

出于这个原因,您通常不应该使用 GET 查询字符串来更改应用程序中的状态。

GET requests are not supposed to have any side effects 并且浏览器将尝试利用这一点来加快页面加载速度,方法是在用户单击页面之前预先请求页面,或者通过缓存页面而不实际从服务器请求它。这些情况中的任何一种都会导致意外行为。此外,如果有人在页面上添加了 ?logout=1 书签,他们会(可能不小心)在 return 访问该页面时随时注销。

最好用POST这个动词。您可以轻松地使用 HTML

标签和提交按钮:

<form action="signup.php" method="POST" id="logout_form">
    <input type="hidden" name="logout" value="1" />
    <input type="submit" value="Logout" />
</form>

在您的 PHP 中,您可以通过执行以下操作来检测是否有人按下了按钮:

if(isset($_POST['logout'])) {
    //log user out
}

Michael 的回答很好(并且被采纳了!),但目前我工作的地方正在进行无障碍审核,所以我有这个想法。屏幕阅读器、使用高对比度自定义样式表的人等无法像处理纯文本那样轻松地处理表单按钮。

此外,我在使用 session_destroy 的(旧)PHP 清除会话中遇到了问题,因此我遍历会话变量并 unset 它们。

<a href="/logout.php">Log out</a>

然后logout.php:

<?php

session_start();

foreach($_SESSION as $sk=>$sv){
  unset($_SESSION[$sk]);
}

header("location: /");

?>