安全的 PHP 注销脚本
这是一个简短的 PHP 教程,介绍如何创建一个简单的用户注销脚本来防范CSRF 攻击。
CSRF 攻击。
如果您还不知道,CSRF代表Cross-Site Request Forgery,这是一种攻击类型,可以欺骗毫无戒心的用户去做他们不打算做的事情。
在我们的注销系统的上下文中,此类攻击可用于诱骗毫无戒心的用户注销网站。
例子。
让我们看一下下面的示例,它假设您的注销脚本位于 logout.php:
<a href="logout.php">http://google.com</a>
上面的 HTML 链接看起来像是指向 Google 网站的链接。但是,如果毫无戒心的用户单击它,他们将退出系统。
会话令牌。
当用户登录您的网站时,您应该向他们提供加密安全令牌。然后,此令牌可用于验证某些操作并防范 CSRF 攻击。
登录脚本中可能包含的示例:
<?php
//start the session.
session_start();
/**
* The code below should be executed after the user has successfully logged in.
* It can also be executed whenever you need to
* give the user a new token.
*/
//create a cryptographically secure token.
$userToken = bin2hex(openssl_random_pseudo_bytes(24));
//assign the token to a session variable.
$_SESSION['user_token'] = $userToken;
//redirect user to home page
header('Location: home.php');
exit;
在上面的 PHP 代码中,我们创建了一个令牌并将其分配给一个会话令牌。
我们的注销链接。
指向 PHP 注销脚本的 HTML 链接应如下所示:
<a href="logout.php?token=<?= $_SESSION['user_token'] ?>">Logout</a>
如您所见,我们在用户登录系统时提供给用户的安全令牌已以称为“令牌”的 GET 参数的形式附加到链接中。
单击此类链接将导致一个 URL,例如:
logout.php?token=27b87f10bb05279a749f19396b34d9550e7945213bec9d36
这将使我们的 PHP 注销脚本知道当用户单击注销按钮时正在使用什么令牌。
我们的 PHP 注销脚本。
最后,在我们的 PHP 注销脚本中,我们通过将查询字符串中的令牌与存储在用户会话中的令牌进行比较来验证它:
<?php
//Start the session as normal.
session_start();
//For backward compatibility with the hash_equals function.
//The hash_equals function was released in PHP 5.6.0.
//It allows us to perform a timing attack safe string comparison.
if(!function_exists('hash_equals')) {
function hash_equals($str1, $str2) {
if(strlen($str1) != strlen($str2)) {
return false;
} else {
$res = $str1 ^ $str2;
$ret = 0;
for($i = strlen($res) - 1; $i >= 0; $i--) $ret |= ord($res[$i]);
return !$ret;
}
}
}
//Get the token from the query string.
$queryStrToken = isset($_GET['token']) ? $_GET['token'] : '';
//If the token in the query string matches the token in the user's
//session, then we can destroy the session and log them out.
if(hash_equals($_SESSION['user_token'], $queryStrToken)){
//Token is correct. Destroy the session.
session_destroy();
//Redirect them back to the home page or something.
header('Location: index.php');
exit;
}
如果令牌有效,我们使用 PHP 的session_destroy函数销毁用户的会话。此特定功能将销毁注册到会话的所有数据。如果令牌无效,则不会发生任何事情并且用户不会注销。
希望此注销教程对您有所帮助!