session_set_cookie_params()在重定向后设置两个cookie

时间:2013-04-23 21:35:58

标签: php cookies session-cookies

我使用了here的登录程序略微修改过的版本,并且遇到了我认为来自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。谢谢!

1 个答案:

答案 0 :(得分:1)


原因:因为example.com和www.example.com是浏览器的两个不同域。


example.com 

是一个更高级别的域名。

www.example.com 

是一个较低级别的域名,位于example.com

通过以下方式将Cookie设置为更高的域名:

setcookie($name, $value, $expire, $path, 'example.com');

也适用于会话cookie:

session_set_cookie_params($lifetime, $path, 'example.com'); 

同样解决了这个问题。

因此它们对www.example.com和example.com都有效

查看setcookie function

的php手册中的域名定义

警告:高级域Cookie有效且可供所有较低级别的网页访问。 example.com的Cookie也可以从mysubdomain.example.com访问。

因此,如果不需要,您应该区分cookie域。


IMHO:

header("Location: https://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]);

不是发送标题,而是回应它以查看正在发生的事情......