我正在使用这里发现的登录脚本的稍微修改版本,并且遇到了我认为来自session_set_cookie_params()的行为,我不理解。
我使用会话、cookie和header()将用户重定向到登录页面,然后再返回到他们请求的页面。我的问题是,尽管初始页面和登录页面使用相同的功能来处理会话和cookie,但设置了两个单独的cookie;一个用于www.example.com,一个用于example.com。这是防止在登录后读取初始页面上设置的会话变量。
下面是一个来自任何请求页面的代码示例:
requireSSL();
sec_session_start();
if(login_check($mysqli) == false) {
$_SESSION['origURL'] = $_SERVER['REQUEST_URI'];
header('Location: https://www.example.com/login.php');
exit();
}
函数如下:
function requireSSL() {
if($_SERVER["HTTPS"] != "on") {
header("Location: https://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]);
exit();
}
}
function sec_session_start() {
$session_name = 'sec_session_id'; // Set a custom session name
$secure = true; // Set to true if using https.
$httponly = true; // This stops javascript being able to access the session id.
ini_set('session.use_only_cookies', 1); // Forces sessions to only use cookies.
$cookieParams = session_get_cookie_params(); // Gets current cookies params.
session_set_cookie_params($cookieParams["lifetime"], $cookieParams["path"], $cookieParams["domain"], $secure, $httponly);
session_name($session_name); // Sets the session name to the one set above.
session_start(); // Start the php session
session_regenerate_id(true); // regenerated the session, delete the old one.
}
虽然我能够通过显式地在session_set_cookie_params()中声明一个域来"修复"这种行为(例如:"example.com"),我希望能够理解为什么首先要设置两个cookie。谢谢!
原因:因为example.com和www.example.com是两个不同的浏览器域。
example.com
是一个高级域。
www.example.com
是一个较低级别的域名,在example.com
将cookies设置为更高域:
setcookie($name, $value, $expire, $path, 'example.com');
也适用于会话cookie:
session_set_cookie_params($lifetime, $path, 'example.com');
同样解决了这个问题。
对于www.example.com和example.com都是有效的
查看php手册中setcookie函数的域定义
警告:高级域cookie是有效的,并且可以被较低级别的所有页面访问。example.com
的Cookie也可以从mysubdomain.example.com
访问。
因此,如果不需要,您应该区分cookie域。
IMHO:
header("Location: https://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]);
不发送报头,而是回显它以查看发生了什么…