[英]session.cookie_domain not working as expected in Plesk / PHP application on 2 subdomains
編輯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中我已經添加以下為“附加配置指令”的php.ini
下兩個 app.example.com
和help.app.example.com
:
session.cookie_domain = ".example.com"
如果我將一個phpinfo()
腳本上傳到help.app.example.com
它會顯示以下session.cookie_domain
:
.example.com
如果我然后在help.app.example.com
上的腳本中運行以下help.app.example.com
:
<?php
session_start();
var_dump($_SESSION);
die;
?>
它輸出一個空數組:
array(0) { }
但是,如果我在app.example.com
上運行等效app.example.com
,則會輸出一個會話數據數組,其中顯示了已登錄用戶的詳細信息(如預期的那樣):
array(15) {
["o_id"]=> (1) "1"
["u_id"]=> string(4) "1745"
...
}
我期待在兩個子域上看到相同的輸出。 為什么這不起作用?
我已閱讀允許php會話轉移到子域,但沒有一個解決問題。
為什么這不起作用?
默認情況下會話保存到服務器上的本地文件,其位置在php.ini的session.save_path
指定,例如session.save_path = /var/lib/php/sessions
,如果是app.example.com和help.app .example.com運行在具有自己的文件系統的2個不同服務器上,或者即使它在同一文件系統上運行但在php.ini中具有不同的session.save_path
指令,它們也不會共享相同的$ _SESSION。
如果您希望2個不同的服務器共享相同的$ _SESSION,可能的解決方案包括使用session_set_save_handler()
創建共享會話存儲數據庫(如想到MongoDB或MySQL),或創建網絡文件系統並設置session.save_path = /path/to/networked/filesystem/mountpoint
php.ini中的session.save_path = /path/to/networked/filesystem/mountpoint
,但這兩種方法都可能導致顯着的性能損失。
...由於cookie在兩個域之間共享, session_id()
將在兩端返回相同的值,可以用作會話數據庫的id,請查看http://php.net/manual/ EN / class.sessionhandlerinterface.php
(如果我有更多時間,我會寫一個樣本課,但我沒時間)
切換到sql-db支持的會話存儲(如MariaDB,MySQL或PostgreSQL),例如:schema:
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();
我只是嘗試復制whit:
並且工作得很好。 在兩種情況下,我都在_Session數組中獲得了值,即使我只將值保存在子域中。
在我的集合中,php.ini的“附加配置指令”對於域和子域是相同的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.