session.cookie_domain在2个子域的Plesk / PHP应用程序中无法正常工作
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了session.cookie_domain在2个子域的Plesk / PHP应用程序中无法正常工作,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4447字,纯文字阅读大概需要7分钟。
内容图文
编辑29/1/2019-该问题有资格获得赏金,但提供的答案均未直接解决该问题.如果您有根据要求回答的答案,请回复
我在同一台物理服务器上配置了2个域:
app.example.com
help.app.example.com
用户登录到https://app.example.com/,该网站由PHP 5.5应用程序组成,该应用程序在成功登录后会将一些数据存储在$_SESSION数组中.
我想配置https://help.app.example.com/,以便可以读取https://app.example.com/上存在的会话数据. help子域上的应用程序是一个用PHP 7构建的内容管理系统.
在Plesk中,我在app.example.com和help.app.example.com的php.ini的“其他配置指令”中添加了以下内容:
session.cookie_domain = ".example.com"
如果我将phpinfo()脚本上载到help.app.example.com,则会显示session.cookie_domain的以下内容:
>当地价值:无价值
>主值:.example.com
如果然后我在help.app.example.com的脚本中运行以下命令:
<?php
session_start();
var_dump($_SESSION);
die;
?>
它输出一个空数组:
array(0) { }
但是,如果我在app.example.com上运行等效项,它将输出会话数据数组,该数组显示已登录用户的详细信息(如预期的那样):
array(15) {
["o_id"]=> (1) "1"
["u_id"]=> string(4) "1745"
...
}
我期望在两个子域上看到相同的输出.为什么这不起作用?
我已经读过Allow php sessions to carry over to subdomains,但是都不能解决问题.
解决方法:
Why is this not working?
默认情况下,会话会保存到服务器上的本地文件中,该文件的位置在php.ini的session.save_path中指定,例如session.save_path = / var / lib / php / sessions(如果有app.example.com和help.app) .example.com在两个具有各自文件系统的不同服务器上运行,或者即使它在同一文件系统上运行,但在php.ini中具有不同的session.save_path指令,它们也不会共享相同的$_SESSION.
如果您希望2个不同的服务器共享相同的$_SESSION,则可能的解决方案包括使用session_set_save_handler()创建共享的会话存储数据库(就像想到的MongoDB或MySQL),或者创建一个联网的文件系统并设置session.save_path = / path /到php.ini中的/ networking / filesystem / mountpoint,但是这两种方法都可能会导致明显的性能损失.
…由于Cookie是在两个域之间共享的,因此session_id()将在两边都返回相同的值,可以将其用作会话数据库的ID,请看一下http://php.net/manual/en/class.sessionhandlerinterface.php
(如果我有更多时间,但我没时间的话,我会写一个示例课)
切换到由sql-db支持的会话存储(例如MariaDB,MySQL或PostgreSQL),例如:
模式:
CREATE TABLE sessions (
id VARCHAR(255) ,
atime BIGINT ,
data BLOB
)
SessionHandlerInterface的实现:
class MySqlSessionHandler implements SessionHandlerInterface
{
protected $db;
public function __construct(string $dsn, string $username, string $password)
{
$this->db = new PDO($dsn, $username, $password, array(
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
));
}
protected function a(string $id) : bool
{
$ret = $this->db->query("UPDATE sessions SET atime = " . (time()) . " WHERE id = " . $this->db->quote($id));
return ($ret->rowCount() > 0);
}
public function close() : bool
{
// TODO: implement locking/race-condition-free session handling?
return true;
}
public function destroy(string $id) : bool
{
$this->db->query("DELETE FROM sessions WHERE id = " . $db->quote($id));
return true;
}
public function gc(int $maxlifetime) : int
{
$this->db->query("DELETE FROM sessions WHERE atime < " . (time() - $maxlifetime));
return 1; // ??? not sure what this return int is supposed to contain, docs doesn't say either
}
public function open(string $save_path, string $session_name) : bool
{
if (!$this->a($session_name)) {
$stm = $this->db->prepare("INSERT INTO sessions (id,atime,data) VALUES(?,?,?);");
$stm->execute(array($session_name, time(), serialize(null)));
}
return true;
}
public function read(string $session_id) : string
{
if (!$this->a($session_id)) {
throw new \InvalidArgumentException("supplied session id does not exist.");
}
return $this->db->query("SELECT data FROM sessions WHERE id = " . $this->db->quote($session_id))->fetch(PDO::FETCH_ASSOC)['data'];
}
public function write(string $session_id, string $session_data) : bool
{
// optimization note: this function can be optimized to do everything in a single query, instead of using a() (which also use a query)
if (!$this->a($session_id)) {
throw new \InvalidArgumentException("supplied session id does not exist.");
}
$stm = $this->db->prepare("UPDATE sessions SET data = ? WHERE id = ?");
$stm->execute(array($session_data, $session_id));
return true;
}
}
用法:
// for DSN documentation, check http://php.net/manual/en/ref.pdo-mysql.connection.php
$handler = new MySqlSessionHandler ('mysql:host=mydb.foo.com;dbname=sessions;charset=utf8mb4','MySqlUsername','MySqlPassword');
session_set_save_handler($handler, true);
session_start();
>现在,他们绝对应该共享会议.
>警告:撰写本文时未经测试,但这在理论上应该可行.
内容总结
以上是互联网集市为您收集整理的session.cookie_domain在2个子域的Plesk / PHP应用程序中无法正常工作全部内容,希望文章能够帮你解决session.cookie_domain在2个子域的Plesk / PHP应用程序中无法正常工作所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。