Это дополнение к сеансам PHP в поддоменах
Я пробовал то, что указано в этом вопросе, и я вижу, что вопрос не был дан.
Поэтому мне нужно иметь сеансы по forum.example.com
( www.example.com
to forum.example.com
)
Что я сделал на www.example.com
session_name("a_name"); session_set_cookie_params(0, '/', '.example.com'); session_start(); echo session_id(); $_SESSION['test'] = 123;
На сайте forum.example.com
session_name("a_name"); session_set_cookie_params(0, '/', '.example.com'); session_start(); echo session_id(); print_r($_SESSION);
Session_id точно такие же, но $ _SESSION ничего не выводит.
Как сделать выход на forum.example.com
123
?
Я попробовал session.cookie_domain = .example.com
но ничего не менял
Когда я forum.example.com
на forum.example.com
он разрушает сеансы www.example.com
, и он делает то же самое с другой стороны, например, если он обнаруживает, что он исходит из другого поддомена и стирает все для обеспечения безопасности.
2 поддомена находятся на одном сервере Debian
Еще одна вещь, которую я заметил, заключается в том, что без session_name
и session_set_cookie_params
он все еще имеет точно такой же session_id, когда я устанавливаю session.cookie_domain
Спасибо
Хорошо, я подумал об этом некоторое время, и я думаю, что у меня это есть.
Прежде всего: поскольку вы получаете одинаковый идентификатор сеанса с обоих серверов, мы можем исключить любые проблемы, связанные с cookie. Очевидно, что вы успешно создаете файл cookie с именем a_name
(хотя я бы рекомендовал только буквенно-цифровые символы для этого имени cookie ) на www.example.com
и успешно прочитал этот a_name
cookie forum.example.com
на forum.example.com
. Но, как вы сказали, вы не получаете никаких данных с forum.example.com
. session.cookie_lifetime = 0
не является проблемой: это означает, что cookie сеанса остается до закрытия браузера .
Мы должны углубиться в обработку сеансов PHP немного дальше. Идентификатор сеанса, который вы читаете с помощью session_id()
относится к файлу на вашем сервере. Как правило, этот файл присутствует в /tmp/sess_$session_id
. Содержимое этого файла представляет собой массив $_SESSION
, сериализованный. (Имейте в виду, что данные не сериализуются так же, как это делает serialize()
в PHP … но это не важно сейчас.).
Я думаю, что это проблема с правами на файл:
/tmp/sess_$session_id
устанавливается с пользователем и группой www.example.com
. forum.example.com
пытается открыть /tmp/sess_$session_id
, но не имеет соответствующих разрешений . print_r($_SESSION);
Решение :
Проверьте конфигурационный файл своего сервера, чтобы убедиться, что www.example.com
и forum.example.com
работают как forum.example.com
ПОЛЬЗОВАТЕЛЬ И ГРУППА . Это очень важно! Для Apache найдите свой файл * .conf:
User youruser Group yourgroup
Для nginx найдите nginx.conf:
user youruser yourgroup;
Если изменение файлов конфигурации сервера не является вариантом, вы должны убедиться, что пользователи, работающие с двумя сайтами, находятся в одной группе.
Вы можете убедиться, что это проблема, сначала загрузив www.example.com
а затем sudo ls -ltc sess_*
в оболочку вашего сервера через SSH (найдите sess_
завершающийся в $session_id
). Затем загрузите forum.example.com
а затем sudo ls -ltc sess_*
снова, чтобы увидеть изменение пользователя и / или группы.
Для этого ответа я сделал несколько предположений:
В моем примере я буду использовать базу данных, так как это идея, которую я использую, а не методы доступа к базам данных / файлу, у меня будут ненужные строки, IE: как подключиться к базе данных.
Если эта концепция является тем, чем вы были, или если кто-то еще хочет, чтобы я заполнил пробелы для полноты, просто оставьте комментарий. С кодом.
Я бы принял совершенно иной подход.
Из того, что я собираю из вашего вопроса и связанного с вами сообщения, вы связались с ним, вы пытаетесь совместно использовать сеанс, используя общее имя сеанса.
class MySessionHandler implements SessionHandlerInterface
Оригинальная идея – не вдаваться в подробности, это просто для справки.
class MySessionHandler implements SessionHandlerInterface { private $savePath; public function read($id) { $id = some_user_authentication_function(); $hash = $_COOKIE['_h']; $result = mysql_query("SELECT sess_data FROM login_table WHERE user_id = {$id} AND hash = {$hash}"); return $result['sess_data']; } public function write($id, $data) { $id = some_user_authentication_function(); $hash = $_COOKIE['_h']; $result = mysql_query("UPDATE login_table SET sess_data = {$data} WHERE user_id = {$id} AND hash = {$hash}"); return ($result === false) ? false : true; } } $handler = new MySessionHandler(); session_set_save_handler($handler, true); session_start();
class customSessionHandler { private $hash; private $id; private $sess_db; public function __construct($db) { $this->hash = $_COOKIE['hash']; $this->id = some_user_authentication_function($this->hash); $this->sess_db = $db; } public function get($key) { $query = "SELECT value ". "FROM ".$this->sess_db. "WHERE user_id = {$id} ". " AND hash = {$hash} ". " AND key = {$key}"; $result = mysql_query($query); return $result['key']; } public function set($key, $val) { $query = "REPLACE INTO ".$this->sess_db. "SET {$key} = {$val} ". "WHERE user_id = {$id} ". " AND hash = {$hash}"; return (mysql_query($query) === false) ? false : true; } } $handler = new customSessionHandler('sess_data'); session_start();
Как было указано в начале, любой код, который не является существенным для объяснения концепции, был удален.
Вещи, которые могут быть не очевидны для всех: – $ key и $ val необходимо дезинфицировать перед отправкой в базу данных. (предотвращение инъекций). Хеш отправляется в ваши функции входа, поэтому хэш может использоваться для очистки данных сеанса, когда это необходимо, также может использоваться при аутентификации пользователя. – Готовые заявления mysql были бы идеальными здесь, поэтому вы можете подготовить два запроса в конструкторе, а затем просто повторно использовать инструкцию для каждого вызова. Затем поместите код закрытия соединения в деструктор.
После мысли
Было бы намного больше безопасности, если бы каждый сайт имел свой собственный хеш.
Затем, если вы обнаружите аномалию безопасности, вы можете просто заблокировать или повторно запросить учетные данные с одного сайта без ущерба для хэша для сети сайтов.
Для реализации этого было бы так же просто, как настроить еще одну таблицу, содержащую: – user_id – имя_сайта (example.com) – hash – timeout – повторная аутентификация
и изменение таблицы session_data, поэтому вместо доступа к парам $ key => $ val хэшем вы получаете доступ к нему user_id.
Спасибо за чтение, надеюсь, это будет полезно кому-то.