我有一个(HTTPS)login.php页面,它仍然是HTTPS(即一旦用户登录后转到帐户仪表板)。现在问题是用户登录到安全仪表板时点击了非敏感页面(HTTP)about-us.php页面,会话不通过HTTP传输,因为我有session.cookie_secure = 1,这意味着用户似乎在HTTP页面上注销。
然而,当用户返回仪表板页面或任何敏感帐户页面时,我被告知他应该仍然登录(即从HTTP返回到HTTPS)?但事实并非如此,他似乎也登录了HTTPS连接?
我相信我错过了造成这个问题的事情。这是我的代码:
这是PHP头文件,在login.php页面上调用它来启动会话:
session_start();
session_regenerate_id(true); /*avoid session fixation attempt*/
/*Create and check how long session has been started (over 5 mins) regenerate id - avoid session hijack*/
if(!isset($_SESSION['CREATED']))
{
$_SESSION['CREATED'] = time();/*time created session, ie from login/contact advertiser/email_confirm only ways for new session to start*/
}
elseif(time() - $_SESSION['CREATED'] > 300)
{
/*session started more than 5 mins(300 secs) ago*/
session_regenerate_id(true); /*change session ID for the current session and invalidate old session ID*/
$_SESSION['CREATED'] = time(); /*update creation time*/
}
/*Check if user is logged in*/
if(!isset($_SESSION['loggedin']))
{
$_SESSION['loggedin']=1;/*used to track if user is logged in on pages*/
}
/*if return false browser supports standard ob_start();*/
if(ob_start("ob_gzhandler")){ob_start();}
这是每个页面上都需要的PHP头文件,用于检查会话是否已启动:
session_start();
$session_errors=0;/* if>0 user not logged in*/
/*check if session is already initiated*/
if(isset($_SESSION['CREATED']))
{
if(time() - $_SESSION['CREATED'] > 300)
{
/*session started more than 5 mins(300 secs) ago*/
session_regenerate_id(true); /*change session ID for the current session and invalidate old session ID*/
$_SESSION['CREATED'] = time(); /*update creation time*/
}
}
elseif(!isset($_SESSION['CREATED'])){$session_errors++;}/*user not logged in*/
/*Check if user is logged in*/
if(!isset($_SESSION['loggedin'])){$session_errors++;}/*user not logged in*/
if(ob_start("ob_gzhandler")){ob_start();}
此外,如果有任何用途,这是在非敏感网页上转换HTTPS的代码,例如about-us.php
if ($_SERVER['SERVER_PORT']!=80)
{
$url = "http://". $_SERVER['SERVER_NAME'] . ":80".$_SERVER['REQUEST_URI'];
header("Location: $url");
}
我的php.ini文件cookie设置
session.cookie_secure=1
session.cookie_httponly=1
session.use_only_cookies=1
session.cookie_lifetime = 0
session.save_path = /tmp
session.save_handler = files
答案 0 :(得分:9)
@rickchristie的描述很好,但我认为他没有提出更好的解决方案。如果您不总是想使用HTTPS(有时候确实有意义; about_us页面不需要是安全的),您可以按照session_start
页面上的建议并使用named sessions来继续前一届会议。这很容易使用;只需使用
session_start
来电
session_name("MySession"); // replace with whatever makes sense
session_start();
在所有安全页面上。
答案 1 :(得分:7)
已回答帮助可能偶然发现此事的人
由于Session lost when switching from HTTP to HTTPS in PHP的答案已经结束,因为您使用session.cookie_secure = 1
,当连接从HTTPS切换到HTTP时,不会传输包含会话ID的cookie。在HTTP连接时,当您session_start()
时,PHP会创建一个新的会话ID,它会替换以前的会话ID。
答案还提出了一个解决方案,使用查询字符串传递会话ID,然后由页面选取。这有点不好的安全漏洞。不要忘记我们首先使用HTTPS的原因!
因此,我建议您使用将所有http请求重定向到https对应项。对您网站中的所有内容使用HTTPS,从CSS,图像到平凡的静态html页面。这实际上是每个应用程序都认真对待安全性的事情。例如,使用HTTP访问github页面将返回:
HTTP/1.1 301 Moved Permanently
Server: nginx/0.7.67
Date: Sun, 08 May 2011 15:43:01 GMT
Content-Type: text/html
Content-Length: 185
Connection: close
Location: https://github.com/
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/0.7.67</center>
</body>
</html>
请记住为什么您首先使用HTTPS,如果您想要完全安全,请使用HTTPS进行所有操作。
在bootstrap上检测请求是否为HTTPS (See this question)。
如果请求是HTTP,则将所有请求重定向到HTTPS主页,或者您可以尝试解析$_SERVER['REQUEST_URI']
并使用parse_url
和http_build_url
将HTTP请求重定向到其HTTPS请求。< / p>
第二种替代解决方案
如果您确实不想为所有内容使用HTTPS,请不要在使用HTTP访问的页面上session_start()
。执行此操作时,将保留安全cookie。
第三种替代解决方案
另一种解决方案是尝试通过IP地址和用户代理检测用户。这不保证是准确的,所以我建议只使用HTTPS来做所有事情。例如,Paypal总是使用HTTPS,即使是普通的静态页面。