我花了几个月的时间在我的域上开发一个应用程序。总的来说,这是一个简单的概念。在开发过程中,我自己将其托管在自己的域中,但最近将其推到了我们实际的域中。问题是会话不是在页面之间创建或保留的,我一生都无法弄清楚为什么。
对下面的代码墙表示歉意,但我更喜欢它而不是理论解释。
让我们从如何在每个页面顶部开始会话开始:
function sec_session_start() {
$session_name = 'login';
$secure = false;
$httponly = true;
ini_set('session.use_only_cookies', 1);
session_set_cookie_params(86400, '/', '.domain.com', $secure, $httponly);
session_name($session_name);
session_start();
session_regenerate_id();
}
然后我如何检查用户是否已登录。我添加了return x;
代替false
用于调试。我将其附加到重定向 URL 中。
function login_check($mysqli) {
if(isset($_SESSION['id'], $_SESSION['login_string'], $_SESSION['type'])) {
$id = $_SESSION['id'];
$login_string = $_SESSION['login_string'];
$user_browser = $_SERVER['HTTP_USER_AGENT'];
if($_SESSION['type'] == 1 || $_SESSION['type'] == 2) // Admin user
{
if ($stmt = $mysqli->prepare("SELECT `password` FROM `users` WHERE `id` = ? LIMIT 1")) {
$stmt->bind_param('s', $id);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows == 1) {
$stmt->bind_result($password);
$stmt->fetch();
$login_check = hash('sha512', $password.$user_browser);
if($login_check == $login_string) {
return true;
} else {
return 1;
}
} else {
return 2;
}
} else {
return 3;
}
} else if($_SESSION['type'] == 3) { // Standard user
if($stmt=$mysqli->prepare("SELECT `password` FROM `proj` WHERE `id` = ? LIMIT 1"))
{
$stmt->bind_param("s", $_SESSION['id']);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows == 1)
{
$stmt->bind_result($db_key);
$stmt->fetch();
$login_check = hash('sha512', $db_key.$user_browser);
if($login_check == $login_string) {
return true;
} else {
return 4;
}
}
}
} else {
return 5;
}
} else {
return 6;
}
}
我有两个登录页面,一个用于管理员,一个用于用户。
Admin:
<?php
ini_set('display_errors','On');
error_reporting(E_ALL);
include_once "../functions.php";
include_once "../db_connect.php";
sec_session_start();
if(login_check($mysqli) === true) {
header('Location: ../index.php');
}
else
{
// Login form
}
Users:
<?php
ini_set('display_errors','On');
error_reporting(E_ALL);
include_once "../functions.php";
include_once "../db_connect.php";
sec_session_start();
if(login_check($mysqli) === true) {
header('Location: ../index.php');
}
else
{
// Login form
}
除了管理员的文件源之外,完全相同login.php
位于/admin
。尽管如此,第一个正确显示登录表单,而第二个将您重定向到index.php
(即使在隐身状态下,这对我来说也是一个谜),导致重定向循环(如index.php
由于未登录而发回)。
除此之外,当我使用正确的凭据登录时,它确实会引导我index.php
只是为了将我重定向回login.php
有错误代码6
.
如果您需要更多信息或代码示例,请发表评论,我现在对自己的项目感到迷失。
任何帮助表示赞赏,
谢谢
12 月 17 日更新:
经过几个小时的调试,我们得出的结论是问题不在于代码,而在于服务器配置。一个简单的例子:
<?php
session_start();
echo session_id();
?>
如果您在生产服务器上打开此文件并刷新页面,它将为每个请求显示一个新的会话 ID。我目前不知道为什么。我已确认会话文件和 cookie 均已创建。它包含正确的信息,并且可以通过具有服务器权限的 SSH 进行访问。确实有些奇怪的行为。
有什么线索吗?