上传到实时服务器后,setcookie 不起作用
Posted
技术标签:
【中文标题】上传到实时服务器后,setcookie 不起作用【英文标题】:setcookie is not working after uploaded to live server 【发布时间】:2021-11-24 15:20:56 【问题描述】:我在 php 中使用 setcookie 来检查访问我网站的用户。问题是当我在我的本地服务器上测试它时它可以工作,cookie 被设置但是当我在 cpanel 中上传页面时,cookie 没有被设置。 以下是我的代码概要:
<?php
session_start();
//set the cookie time to desired value;
setcookie("user", "abc", time()+3600);
//some other codes
if(!isset($_COOKIE["user"]))
//some other codes
?>
任何帮助将不胜感激。谢谢
【问题讨论】:
setcookie()
函数会将一些 HTTP 标头添加到您的响应中,以便您的浏览器存储一个名为“user”的 cookie。当您还启动了一个会话时,它还会要求您的浏览器存储另一个名为“PHPSESSID”的 cookie。 $_COOKIE
数组在第一个页面加载时为空,因为您的浏览器在第一次访问之前没有它们。如果你进入浏览器检查器,你应该找到它们。现在,如果您重新加载页面,浏览器将在请求中发送这些 cookie,然后它们将显示在 var_export($_COOKIE)
中。检查 HTTP 标头是否正确。
现在,我有一个问题:您需要设置另一个cookie“用户”的原因是什么?为什么不将它存储在 PHP 会话数组 $_SESSION
中?解释您正在尝试做什么可能会很有趣,因为我们可以帮助您找到解决问题的最佳方法。
它在我的本地系统上工作,但我在服务器上遇到问题 cookie 没有设置任何解决方案!
我为用户设置了 cookie,即使在浏览器窗口像所有社交媒体网站一样关闭后也能登录
然后检查 HTTP 响应,看看是否有 Set-Cookie: user=abc; expires=Mon, 04-Oct-2021 07:53:39 GMT; Max-Age=3600
标头。如果它丢失了,那么好的,你的服务器有一个特定的配置或禁用的东西。
【参考方案1】:
关于我在 cmets 中的问题的答案,您可能只需要修改会话的 cookie 生命周期,而不是创建另一个“用户”cookie。
// TTL (Time To Live) of the cookie stored in the browser.
ini_set('session.cookie_lifetime', 432000); // 5 days
// On the server side, the garbage collector should delete
// old sessions too, after the same TTL.
ini_set('session.gc_maxlifetime', 432000); // 5 days
// Fire the garbage collector only every 100 requests.
ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 100);
在代码的开头执行此操作,通常在应用程序引导程序中包含的 config.php
文件中。
你可以看到更多in the PHP session configuration。
关于生命周期有一个小问题:cookie 会在生命周期设置后过期,但是由于 cookie 是创建的,所以在你第一次登录时发起会话的那一刻。
通常,您希望 cookie 的生命周期从最后一个用户的操作开始。您可以通过更新 cookie 来做到这一点,以便 PHP 重新发送 Cookie HTTP 标头以覆盖它。我还添加了一些其他应该在 PHP 会话中进行的安全设置。所有内容都在下面的运行示例中进行了注释:
<?php
/**
* Testing PHP cookie settings and improve security.
*/
// The cookie lifetime in seconds.
define('COOKIE_LIFETIME', 10);
// Simulate user's data from the database.
$user_mail = 'james.bond@gmail.com';
// A salt per user is good. It avoids an attacker to be able
// to calculate the session cookie name himself if he discovers that
// it is just done by hashing the user's e-mail.
$user_salt = 'nbVzr432';
// Detect if we are over HTTPS or not. Needs improvement if behind a SSL reverse-proxy.
// It's just used for the cookie secure option to make this POC work everywhere.
$is_https = isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']);
// On the PHP server side, the garbage collector should delete
// old sessions after the same lifetime value.
ini_set('session.gc_maxlifetime', COOKIE_LIFETIME);
// Fire the garbage collector only every 100 requests to save CPU.
// On some OS this is done by a cron job so it could be commented.
ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 100);
// Improve some session settings:
ini_set('session.use_cookies ', 1);
ini_set('session.use_only_cookies ', 1);
ini_set('session.use_strict_mode ', 1);
// This POC will just print some plain text.
header('Content-Type: text/plain; charset=utf-8');
// Change the session cookie name so that an attacker cannot find it.
$session_cookie_name = 'SESS_' . sha1($user_mail . $user_salt);
// Store all the session cookie options in an array.
$session_cookie_options = [
// Set the cookie lifetime (the browser sets an expire to delete it automatically).
'lifetime' => COOKIE_LIFETIME,
// The cookie path defines under which relative URL the cookie should be sent.
// If your app is running under https://your-site.com/shop/ then the cookie path
// should be set to /shop/ instead of the default / as there's no reason to send
// your shop's session cookie to another app running at https://your-site.com/forum/.
'path' => '/',
// Cookie domain. Use null to let PHP handle that. But if you want a session
// cookie accross multiple sub-domains such as forum.your-site.com and shop.your-site.com
// then you should set the domain to ".your-site.com".
'domain' => null,
// If we are in HTTPS then don't let cookies be sent over HTTP.
// Here I used $is_https to make it run everywhere but if you have
// HTTPS on your domain then replace it by 1 to lock it!
'secure' => $is_https ? 1 : 0, // IMPORTANT: Replace by 1 if you have both HTTP and HTTPS enabled.
// Don't let javascript access the session cookie.
'httponly' => 1,
// If another site has a link pointing to your website then don't send
// the session cookie (POST or GET). This mitigates somes kind of attacks.
'samesite' => 'Strict',
];
// Apply all the session cookie settings without ini_set() for maximum portability:
session_name($session_cookie_name);
session_set_cookie_params($session_cookie_options); // Since PHP 7.3 only
session_start();
// If the session cookie has been sent by the browser then it might have an expiration
// date to early (because it is set only once at the creation of the session).
// Instead we would like it to expire with our lifetime since the last user's
// action. To do that we have to use setcookie() to resend the cookie in order
// to update/overwrite it to have a new expiration date in the browser.
if (isset($_COOKIE[$session_cookie_name]) && $_COOKIE[$session_cookie_name] == session_id())
$cookie_options = $session_cookie_options;
unset($cookie_options['lifetime']); // This one is replaced by expires below.
$cookie_options['expires'] = time() + COOKIE_LIFETIME;
setcookie($session_cookie_name, session_id(), $cookie_options);
// Now that HTTP headers have been set, we are allowed to start printing output.
// If the user is already logged and his caddie is empty then fill it with some
// random stuff. It will stay saved until the session expires.
if (isset($_SESSION['session_creation_date']) && !isset($_SESSION['shop_caddie']))
$_SESSION['shop_caddie'] = [
'T-shirt' => [
'quantity' => rand(1, 3),
'color' => 'red',
],
'Beer' => [
'quantity' => (['2dl', '3dl', '5dl'])[rand(0, 2)],
]
];
// If the session is empty, let's init it with the creation date for the showcase.
if (empty($_SESSION))
$_SESSION['session_creation_date'] = date('r');
print 'Recieved cookies from the browser = ' . var_export($_COOKIE, true) . "\n\n";
print 'Session data = ' . var_export($_SESSION, true) . "\n\n";
【讨论】:
以上是关于上传到实时服务器后,setcookie 不起作用的主要内容,如果未能解决你的问题,请参考以下文章