http://sitename.com
切换到 https://sitename.com
。这将导致$_SESSION
变量丢失。该网站具有有效的SSL证书,这可能有些用处。session_start()
启动脚本。如果浏览器设置了会话ID cookie,则session_start()
将使用该会话ID。如果浏览器没有设置会话ID cookie,则session_start()
将创建一个新的会话ID。session_id()
函数设置它。session_id()
还方便地返回会话ID作为字符串。...
$currentSessionID = session_id();
...
将$currentSessionID
变量设置为当前会话ID,并且
...
session_id($aSessionID);
...
将浏览器中的sessionID cookie设置为$aSessionID
。来自PHP: session_id
以下是两个脚本的示例。一个通过HTTP访问,另一个通过HTTPS访问。它们必须在同一服务器上以维护会话数据。
脚本1(HTTP):
<?php
// This script will create a session and display a link to your secure server address
// to transfer your session ID. In this example, the secure page to receive the session
// ID is located at http://www.yoursite.com/safePages/securePage.php
// Start a session using the current session ID stored in a cookie, or create
// a new session if none is set.
session_start();
$currentSessionID = session_id();
// Set a variable that will be retrieved with the HTTPS script.
$_SESSION['testvariable'] = 'It worked';
// $secureServerDomain is the domain of your secure server
$secureServerDomain = 'www.yoursite.com';
// $securePagePath is the path to the page that will receive and set the session ID.
$securePagePath = '/safePages/securePage.php'
echo '<a href="https://' . $secureServerDomain . $securePagePath . '?session="' . $currentSessionID . '">Click here to transfer your session to the secure server</a>';
?>
脚本2(HTTPS):
<?php
// Retrieve the session ID as passed via the GET method.
$currentSessionID = $_GET['session'];
// Set a cookie for the session ID.
session_id($currentSessionID);
// Start a session.
session_start();
// Test retrieval of variable set when using HTTP.
if (!empty($_SESSION['testvariable'])) {
echo $_SESSION['testvariable'];
} else {
echo 'It did not work.';
}
?>
当我以前遇到这个问题时,我想出了上面的快速修复方法,但我刚刚想起了问题的根本原因。我从http://www.example.com/page.php转到https://example.com/page.php(注意缺少“www”)。确保http://www.example.com/page.php将链接到https://www.example.com/page.php,http://example.com将链接到https://example.com/page.php。
附注:我实际上没有运行这些脚本,因此可能会有一两个拼写错误,导致它们无法正常运行。
$hash = md5($currentSessionID.'somesecretsalt')
,然后URL应该看起来像 ?session='.$currentSessionID.'&hash='.$hash
。在目标站点上,你可以检查 md5($_GET['session'].'somesecretsalt') == $_GET['hash']
是否成立。这样你就可以知道,会话ID不是随意制造的。会话ID必须与服务器生成的哈希值匹配(当使用长盐值时,几乎不可能破解)。 - Trolley/etc/php.d/suhosin.ini
中设置suhosin.session.cryptdocroot = Off
来解决它。suhosin.session.cryptdocroot
的suhosin手册,请参见http://www.hardened-php.net/suhosin/configuration.html#suhosin.session.cryptdocroot。suhosin.cookie.cryptdocroot
。 - mrwalker你不能在不同的域之间传递会话值。你必须使用 http post-get 或数据库来传递你的值。为了安全起见,你可以将所有的值连接成一个字符串并使用。
sha1($string)
将其与您的值一起发布并为其他页面获取的值计算sha1,然后比较哈希值。
不要在不同域上使用post方法,否则浏览器会显示安全消息。
使用url进行get方法不安全,您需要在重定向页面上请求密码以允许系统中的get参数。
如果需要安全性,请勿使用cookies。
我建议的方法是,将值保存在数据库中并生成一个密钥,然后使用您的密钥创建重定向链接,使用具有密钥的get参数转发用户页面,然后被重定向到的页面获取该密钥,提取数据并删除密钥。您可以使用sha1生成密钥。
PAGE 1---
$key=sha1($allvalsconcat);
//insert your session values to a database also the key in a column
header("Location: page2.php?key=".$key);
PAGE 2---
// select from database where key=$_GET["key"];
// delete from table where key=$key
这是相当安全的。
可能发生的事情: 脚本输入随机值到参数“key”中,从而加载数据到您的内存中?
这不会发生,因为在使用后您会删除该条目。 一些常见的误解是获取值是不安全的,应该始终避免。
如果想要完美的性能,可以将表引擎类型设置为mysql中的“memory”。
使用GET方法在页面之间传输会话ID
通过POST方法提交会话ID
使用文件保存会话
使用Cookies进行会话管理
使用数据库保存会话
以下示例可用于使用GET方法传输:
文件:http.php ……………
<?php
session_start();
$sessionID = session_id();
$_SESSION['demo'] = ‘Demo session between HTTP HTTPS’;
echo ‘<a href=”https://www.svnlabs.com/https.php?session=’.$sessionID.’”>Demo session from HTTP to HTTPS</a>’;
?>
文件:https.php ……………
<?php
$sessionID = $_GET['session'];
session_id($sessionID);
session_start();
if (!empty($_SESSION['demo'])) {
echo $_SESSION['svnlabs'];
} else {
echo ‘Demo session failed’;
}
?>
IE7:此页面包含安全和非安全项目
您必须在页面上使用相对路径来引用所有静态资源,如css、js、图像、flash等,以避免IE消息中的安全和非安全项目...
IE消息
看起来您的会话cookie是使用安全标志创建的,但由于结帐页面的URL存在问题,因此会话cookie未被传递。
或者,您的会话cookie不安全 - 只是结帐页面的URL有足够的差异({{link1:http://mysite.com}}与{{link2:http://www.mysite.com}}),浏览器不会发送cookie。
如果您想了解更多关于从http切换到https和反之亦然的信息,请查看{{link3:我的有关选择性ssl的文章}} :-)
除了大多数人在这里提到的传输加密信息之外,我建议您将其视为通过第三方API传输敏感信息。您如何知道有人没有欺骗请求?根据您的设置的敏感程度,有许多协议可以真正确认请求的真实性。如果不小心,您会使帐户面临被攻击的风险。
即使它在同一台服务器上,也要考虑以下内容:
当有人跟随链接、表单操作等传递加密密钥时,有什么可以防止他们在到达您网站的安全版本之前嗅探它?如果我在公共WIFI点,那并不是太牵强。我可以假装是您的网站,将请求重定向到我的笔记本电脑,抓取令牌,并将访问者重定向回原来的位置。他们会认为这是一个故障,并且毫不知情。现在我可以登录为他们,可能使用他们的信用卡购买价值10,000美元的物品并将其运送到其他地方。您在此处采取的谨慎程度应与敏感程度相匹配。
此外,确保您过期令牌(仅限一次使用,在X秒后过期等等),但我还建议在两端上使用Post-Redirect-Get模式,即:不要在页面上或非安全站点的形式中显示直接链接,而是显示一个链接,然后在后端重定向(并处理所有令牌/加密内容)。到达安全版本时,执行相同操作(不要在URL中留下"?token=asdfjalksfjla"参数;将其重定向)。
因此,正式的基于令牌的系统旨在解决这个问题,但为此实现OAuth可能有些过度设计。在执行之前花些时间规划潜在漏洞。仅仅因为很难猜测令牌并不意味着这是不可能的(或者可能会有碰撞等问题),因此请做好计划。
您可能还需要比PHP内置处理程序更复杂的会话管理系统。我不知道是否可以强制PHP在多个访问之间继续会话(切换协议时会这样处理)。
考虑为所有页面使用HTTPS,这是避免此问题的最简单方法,也将提高您网站的安全性。
如果对于您来说所有页面使用SSL不是一个选项,那么您可以使用以下方法:在HTTP和HTTPS页面之间切换并使用安全会话cookie。其背后的想法是,您保留会话cookie不安全(因此可用于HTTP和HTTPS页面),但有第二个安全cookie来处理身份验证。这是分离“维护会话”和“身份验证”两个关注点的好方法。
我已经通过这个方法得到了解决方案。请尝试一下。
$_SESSION['test'] = 'test';
session_regenerate_id(true);
header("Location: /");// the header must be sent before session close
session_write_close(); // here you could also use exit();