PHP _Session变量在php文件之间丢失。为什么?

时间:2018-11-25 14:11:40

标签: php session-variables html-form

我知道,按照标题,此问题已在此处多次回答,但没有帖子提供给我有效的解决方案。所以我去:

问题:

我有index.php文件。这是具有用户/密码字段和登录按钮的基本html表单。有时,在登录按钮中,一个名为login()的函数会为密码生成一个哈希值。然后针对数据库验证user + hash。如果访问有效,则向SESSION添加一些值,返回true,然后该表单加载一个名为process_login.php的php文件,我所做的就是检查用户是否为admin并根据那。到目前为止,一切都很好。

process_login.php加载正确的网站,并且可以看到SESSION值(我尝试打印它们,一切正常)。

此值用于在加载任何网站之前检查当前用户是否具有有效的会话(已登录)。 这就是我将变量添加到SESSION btw

的方式
$user_id = preg_replace("/[^0-9]+/", "", $user_id);    
$username = preg_replace("/[^a-zA-Z0-9_\-]+/", "", $user);
$_SESSION['user_id'] = $user_id;
$_SESSION['username'] = $username;
$_SESSION['login_string'] = hash('sha512', $db_password . $user_browser);

问题来了: process_login.php加载正确的网站home.php。然后,Home.php使用一个名为login_check()的函数检查会话是否有效。  此功能的第一行是

 // Check if all session variables are set 
if (isset($_SESSION['user_id'], $_SESSION['username'], $_SESSION['login_string'])) {

那失败了。 SESSION是一个空数组,我不知道为什么。

读到可能的原因后,人们总是建议在需要使用SESSION的每个php文件的开头调用start_session()。好吧,我知道。 我称它为index.php,process_login.php和home.php,但是……什么都没有。我唯一不叫它的地方是一个functions.php,我用来声明上面提到的所有函数。它只是一个包含的文件,没有任何加载。

这是我开始会议的方式:

function sec_session_start() {
 $session_name = 'sec_session_id';   // Set a custom session name 
 $secure = SECURE;

 // 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.
}

然后,在每个文件的开头,我设置了这段代码(代码可能会有所不同,因为包含文件可能不同)

<?php
 include_once 'includes/db_connect.php';
 include_once 'includes/functions.php';
 sec_session_start();
?>

如您所见,最后,我调用session_regenerate_id()。我怀疑它可能正在删除我的SESSION中的所有内容,因此我发表了评论。没有改变。 home.php始终无法查看SESSION中的内容。

任何帮助将不胜感激。如果需要,我可以提供更多代码。 另外,值得一提的是,这在本地(XAMPP)和在线(Web主机)均失败。

欢呼

更新:

创建SESSION时,我正在使用session_set_cookie_params()函数进行设置。 SECURE参数是设置为true的定义的布尔值。如果我将其更改为FALSE,则一切正常。我知道XAMPP不能使用https(除非您安装了证书等),但是我希望它可以在服务器中工作(它使用安全的ssh组合,所以使用https)。仔细检查重定向是否使用https。

1 个答案:

答案 0 :(得分:0)

问题现在已解决。 正如他们所说,我做的一切都正确。问题是这样的: 在为会话设置Cookie参数时,我将安全标志设置为TRUE。这将强制将Cookie只能通过安全连接(更多信息session_set_cookie_params

传递。

问题是每个人都使用www来访问该网站。或什么都不做(实际上是http),并且由于它不是安全连接,因此使得cookie无法通过。但是,如果您使用https(或https://www)访问,则一切正常(我在服务器中安装了ssl证书)。 解决方案是在服务器的.htacess文件中使用重定向,以使所有内容都重定向到https://www以强制执行安全访问。 我用了这段代码

RewriteEngine On
RewriteCond %{HTTPS} off
# First rewrite to HTTPS:
# Don't put www. here. If it is already there it will be included, if not
# the subsequent rule will catch it.
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Now, rewrite any request to the wrong domain to use www.
# [NC] is a case-insensitive match
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

感谢大家的建议。

干杯!