Fre*_*rik 9 php session redirect
我花了几个月的时间在我的域上开发应用程序.这是一个简单的概念.在开发过程中,我自己在我自己的域上托管它,但最近把它推到了我们的实际域.问题是会话不是在页面之间创建或保存的,我不能为我的生活找出原因.
为下面的代码墙道歉,但我更喜欢理论解释.
让我们从每个页面顶部的会话开始:
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();
}
Run Code Online (Sandbox Code Playgroud)
然后我如何检查用户是否已登录.我添加了return x;
而不是false
用于调试.我将此附加到重定向网址.
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;
}
}
Run Code Online (Sandbox Code Playgroud)
我有两个登录页面,一个用于管理员,一个用于用户.
管理员:
<?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
}
Run Code Online (Sandbox Code Playgroud)
用户:
<?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
}
Run Code Online (Sandbox Code Playgroud)
除了管理员login.php
所在的文件来源之外,它们完全相同/admin
.尽管如此,第一个显示正确的登录表单,而第二个重定向到您index.php
(即使在隐身,对我来说是一个谜),导致重定向循环(index.php
将其发回给nog登录).
除此之外,当我使用适当的凭据登录时,它确实指示我index.php
只是将我重定向回login.php
错误代码6
.
如果您想了解更多信息或代码示例,请发表评论,我现在感到迷失在自己的项目中.
感谢任何帮助,谢谢
更新17月12日:
经过几个小时的调试,我们得出结论,问题不在于代码,而在于服务器配置.一个简单的例子:
<?php
session_start();
echo session_id();
?>
Run Code Online (Sandbox Code Playgroud)
如果在生产服务器上打开此文件并刷新页面,则会在每个请求中显示一个新的会话ID.我目前不知道为什么.我已经确认创建了会话文件以及cookie.它包含正确的信息,可以通过SSH访问服务器权限.真是一些奇怪的行为.
有线索吗?
我已经完成了你的代码,除了只有一件事,我没有找到任何不寻常的东西.
你永远不应该==
用于字符串比较===
是好的.
$something = 0;
echo ('password123' == $something) ? 'true' : 'false';
Run Code Online (Sandbox Code Playgroud)
运行上面的代码,您将找到会话丢失的原因.在您的函数login_check中,您将==
用于比较两个字符串
if($login_check == $login_string)
Run Code Online (Sandbox Code Playgroud)
替换为:
if($login_check === $login_string)
Run Code Online (Sandbox Code Playgroud)
除此之外,每件事都绝对精美.如果改变这个小东西不能解决你的问题,那就告诉我.
您在会话开始之前连接到DB.我建议你导入你的功能,然后开始你的会话,然后连接到你的数据库.
include_once "../functions.php";
sec_session_start();
include_once "../db_connect.php";
Run Code Online (Sandbox Code Playgroud)
检查会话是否已经开始并确保只完成一次:
对于 PHP >= 5.4:
function sec_session_start() {
if (session_status() == PHP_SESSION_NONE) {
$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();
}
}
Run Code Online (Sandbox Code Playgroud)
PHP 5.4 之前:
function sec_session_start() {
if (session_id() == '') {
$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();
}
}
Run Code Online (Sandbox Code Playgroud)
另外,为什么每次都要重新生成会话?