我创建了一个相对较小的基于php / mysql的网站,并将其托管在运行Red Hat 6.4,Apache / 2.2.15的服务器上。要访问该站点,用户需要进行身份验证。
现在出现了一个奇怪的问题。当我启动服务器时,该站点最初运行正常,但大约12-24小时后,php会话停止工作。当用户尝试登录时,他们的凭据从数据库成功检索,登录脚本设置会话变量,但当他们被重定向到主页时 - 会话变量丢失,所以主页认为他们不是登录后,它们将重定向回登录页面。该网站使用不多,约有50名注册用户,每天登录不到100次。此外,该网站需要注册邀请代码,因此机器人在网站上的可能性非常小。
下面是用于启动会话,记录用户以及检查他们是否经过身份验证的PHP函数(代码的灵感来自http://www.wikihow.com/Create-a-Secure-Login-Script-in-PHP-and-MySQL):
function SecSessionStart() {
$session_name = 'sec_session_id'; // Set a custom session name
$secure = false;//https is not enforced
// This stops JavaScript being able to access the session id.
$httponly = true;
// Forces sessions to only use cookies.
if (ini_set('session.use_only_cookies', 1) === FALSE) {
header("Location: ../error.php?err=Could not initiate a safe session (ini_set)");
exit();
}
// Gets current cookies params.
$cookieParams = session_get_cookie_params();
session_set_cookie_params($cookieParams["lifetime"],
$cookieParams["path"],
$cookieParams["domain"],
$secure,
$httponly);
// Sets the session name to the one set above.
session_name($session_name);
session_start(); // Start the PHP session
session_regenerate_id(); // regenerated the session, delete the old one.
}
function Login($username, $password) {
$username=trim($username);
if (CheckUserCredentials($username, $password))
{
$userId=GetUserIdByUsername($username);
$hashedPass=hash("sha512",$password);
$user_browser = $_SERVER['HTTP_USER_AGENT'];
$_SESSION['user_id'] = $userId;
// XSS protection as we might print this value
$username = strtolower($username);
$_SESSION['username'] = $username;
$_SESSION['login_string'] = hash('sha512', $hashedPass.$user_browser);
// Login successful.
session_write_close();
return true;
}
else {
session_write_close();
return false;
}
}
function LoginCheck() {
// Check if all session variables are set
if (isset($_SESSION['user_id'], $_SESSION['username'], $_SESSION['login_string']))
{
$user_id = $_SESSION['user_id'];
$login_string = $_SESSION['login_string'];
$username = $_SESSION['username'];
// Get the user-agent string of the user.
$user_browser = $_SERVER['HTTP_USER_AGENT'];
$hash=GetPasswordHashByUserId($user_id);
if ($hash==null)
{
session_destroy();
session_write_close();
return false;
}
$login_check = hash('sha512', $hash.$user_browser);
if ($login_check == $login_string) {
// Logged In
session_write_close();
return true;
} else {
// Not logged in
session_destroy();
session_write_close();
return false;
}
}
session_destroy();
session_write_close();
return false;
}
为了测试我认为问题与会话有关的假设,我制作了以下php页面,并且我已经在正常运行时间检查器上每隔5分钟设置一次监控:
<?php
require_once("include/authentication.php");
SecSessionStart();
$_SESSION['sessionCheck'] = "The cookie was successfully saved and retrieved";
session_write_close();
$_SESSION['sessionCheck']="";
SecSessionStart();
if (isset($_SESSION['sessionCheck']))
{
echo($_SESSION['sessionCheck']);
}
session_destroy();
session_write_close();
?>
就像我怀疑的那样,页面返回了正确的答案大约20个小时,然后我收到一个警告,表明页面没有显示成功字符串。收到警报后,网站上的登录部分也无法正常工作。我已经尝试重新启动httpd进程以恢复会话,但这没有帮助。只有在完成服务器重启后,事情才会恢复正常。
我尝试在SO和其他网站上搜索我的问题,我发现了一些与某种程度相关的问题,但它们并不完全适合我的情况。我的问题和其他类似的问题之间的主要区别在于,网站在开始时工作得非常好,但是经过一段时间后,会话一直都会失败。其他海报有问题,他们不时丢失会议或会议根本没有工作。
对此问题可能来源的任何暗示都将不胜感激。如果您需要我提供的任何有用的信息,请告知我们。
谢谢