Сеансы PHP в поддоменах
Я пытаюсь настроить следующее:
auth.domain.com
sub1.domain.com
sub2.domain.com
где, если пользователь посещает sub1.domain.com или sub2.domain.com, и они не вошли в систему, они переходят на auth.domain.com и могут входить в систему. sub1.domain.com и sub2.domain.com - это два отдельных приложения, но используют те же учетные данные.
Я попытался установить следующее в моем php.ini:
session.cookie_domain = ".domain.com"
но, похоже, он не передает информацию из одного домена в другой.
[изменить]
Я попробовал следующее:
sub1.domain.com/test.php
session_set_cookie_params(0, '/', '.domain.com');
session_start();
print session_id() . "<br>";
$_SESSION['Regsitered'] = 1;
echo '<a href="#" onclick="location.href='http://auth.domain.com/test.php'; return false;">Change Sites</a>'
auth.domain.com/test.php
session_set_cookie_params(0, '/', '.domain.com');
session_start();
print session_id() . "<br>";
$_SESSION['Checked'] = 1;
print_r($_SESSION);
Идентификаторы сеанса точно такие же, но когда я вывожу переменную $_SESSION, она не отображает оба ключа, только любой ключ, который я устанавливал для каждого домена.
[Изменить 2]
Я обновил [Edit]
Ответы
Ответ 1
Я не знаю, существует ли проблема, но я просто столкнулся с той же проблемой и решил установить ее имя перед вызовом session_set_cookie_params():
$some_name = session_name("some_name");
session_set_cookie_params(0, '/', '.some_domain.com');
session_start();
Я ничего не изменил в своем php.ini, но теперь все работает нормально.
Ответ 2
Одна вещь, которая может загадочно запретить чтение сессионных данных в субдомене, несмотря на то, что файлы cookie, правильно настроенные на .domain.com
, являются патчем PHP Suhosin. Вы можете настроить все правильно, в соответствии с примерами в вопросе, и оно может просто не работать.
Отключите следующие настройки сеанса Suhosin, и вы вернулись в бизнес:
suhosin.session.cryptua = Off
suhosin.session.cryptdocroot = Off
Ответ 3
Попробуйте использовать:
session.cookie_domain = "domain.com"
Вместо:
session.cookie_domain = ".domain.com"
Обратите внимание на отсутствующий период.
Будьте осторожны с этим, потому что он не поддерживается всеми браузерами.
Ответ 4
Если бы эта точная проблема - я хотел, чтобы значения сеанса, созданные на x.example.local, были доступны на example.local и наоборот.
Все найденные решения говорят об изменении домена сеанса, используя
php_value session.cookie_domain .example.local
в .htaccess(или через php.ini или через ini_set).
Уловкой я устанавливал session.cookie_domain
для всех поддоменов (до сих пор хорошо), а также для основного домена. Установка session.cookie_domain
в основном домене, по-видимому, не имеет значения.
В основном, как это сработало для меня:
- установите
session.cookie_domain
для ВСЕХ SUBDOMAINS.
- не устанавливать его для основного DOMAIN
О да, пожалуйста, убедитесь, что у домена есть TLD (в моем случае .local). Протокол Http не позволяет сохранять файлы cookie/сеансы в домене без .tld(то есть localhost не будет работать, но stuff.localhost будет).
EDIT. Также убедитесь, что вы всегда очищаете куки файлы браузера во время тестирования/отладки сессий по субдоменам. Если вы этого не сделаете, ваш браузер всегда отправит старый файл cookie сеанса, который, вероятно, еще не имеет правильного файла cookie_domain. Сервер оживит старый сеанс, и поэтому вы получите ложные отрицательные результаты. (во многих сообщениях он упомянул использовать session_name ( "материал" ) для того же самого эффекта)
Ответ 5
Я решил это так:
ini_set('session.cookie_domain', '.testdomain.dev');
session_start();
Потому что я работал над localhost
ini_set('session.cookie_domain', '.localhost');
не работал, он видит .localhost как верхний слой вместо .com/.local/... (я подозреваю)
Я также использовал .dev, потому что работа с OS X, похоже, не разрешает .com как сначала в HOSTS
Ответ 6
Используйте его для каждого домена/поддомена:
session_name('name');
ini_set('session.cookie_domain', '.example.com');
ini_set('session.save_path', '/var/lib/php/session');
session_start();
Путь для session.save_path
может быть другим для вашего случая, но он должен быть одинаковым для каждого домена/поддомена. По умолчанию это не всегда верно.
Ответ 7
Я подтвердил. joreon ответ правильный. Я не могу комментировать, потому что моей репутации недостаточно, поэтому я размещаю свой комментарий здесь.
Определите константу в файле конфигурации. Если вы хотите изменить его, не нужно изменять целые файлы.
define('ROOT_DOMAIN', 'mysite.com');
define('PHP_SESSION_NAME', 'MYSITE');
Имя сеанса не может состоять только из цифр, должно присутствовать хотя бы одна буква. В противном случае каждый раз генерируется новый идентификатор сеанса.
Используйте следующий код, чтобы начать использовать сеанс
session_name(PHP_SESSION_NAME);
session_set_cookie_params(0, '/', '.' . ROOT_DOMAIN);
session_start();
Я использую эту функцию:
function load_session() {
if (session_status() == PHP_SESSION_NONE) {
session_name(PHP_SESSION_NAME);
session_set_cookie_params(0, '/', '.' . ROOT_DOMAIN);
session_start();
}
else {
if (session_name() != PHP_SESSION_NAME) {
session_destroy();
session_name(PHP_SESSION_NAME);
session_set_cookie_params(0, '/', '.' . ROOT_DOMAIN);
session_start();
}
}
}
load_session(); // put it in anywhere you want to use session
Ответ 8
Используйте это, он работает:
ini_set('session.cookie_domain',
substr($_SERVER['SERVER_NAME'],strpos($_SERVER['SERVER_NAME'],"."),100));
Ответ 9
Поддомен и корневой домен Cookie Sessions Комбинированное использование
Ресурс: http://php.net//manual/tr/function.session-set-cookie-params.php
Я тестировал работы
sub.exampledomain.com/sessionadd.php?id=123
exampledomain.com/sessionview.php // 123
- Коды
<?php
$currentCookieParams = session_get_cookie_params();
$rootDomain = '.example.com';
session_set_cookie_params(
$currentCookieParams["lifetime"],
$currentCookieParams["path"],
$rootDomain,
$currentCookieParams["secure"],
$currentCookieParams["httponly"]
);
session_name('mysessionname');
session_start();
setcookie($cookieName, $cookieValue, time() + 3600, '/', $rootDomain);
?>
Ответ 10
Я понимаю, что вы не хотите что-то вроде OpenID, как предлагает Joel, но вы хотите иметь доступ к данным сеанса через несколько доменов.
Единственная возможность, которую я могу рассматривать как решение этой проблемы, - это хранить данные сеанса в базе данных и вытаскивать ее из этой базы данных.
Ответ 11
Я знаю, что это старо, но это отлично подходит для меня с несколькими доменами и поддоменами в одном окне.
<?php
define('site_domain','domain.com');
session_set_save_handler('_open',
'_close',
'_read',
'_write',
'_destroy',
'_clean');
function _open(){
global $_sess_db;
$db_user = 'user';
$db_pass = 'pass';
$db_host = 'localhost';
if ($_sess_db = mysql_connect($db_host, $db_user, $db_pass)){
return mysql_select_db('database', $_sess_db);
}
return false;
}
function _close(){
global $_sess_db;
return mysql_close($_sess_db);
}
function _read($id){
global $_sess_db;
$id = mysql_real_escape_string($id);
$domain = mysql_real_escape_string(site_domain);
$agent = mysql_real_escape_string(isset($_SERVER['HTTP_USER_AGENT']));
$sql = "SELECT data
FROM sessions
WHERE id = '$id' AND domain = '$domain' AND agent = '$agent'";
if ($result = mysql_query($sql, $_sess_db)){
if (mysql_num_rows($result)){
$record = mysql_fetch_assoc($result);
return $record['data'];
}
}
return '';
}
function _write($id, $data){
global $_sess_db;
$access = time();
$id = mysql_real_escape_string($id);
$access = mysql_real_escape_string($access);
$data = mysql_real_escape_string($data);
$domain = mysql_real_escape_string(site_domain);
$agent = mysql_real_escape_string(isset($_SERVER['HTTP_USER_AGENT']));
$sql = "REPLACE INTO sessions
VALUES ('$id', '$access', '$data', '$domain', '$agent')";
return mysql_query($sql, $_sess_db);
}
function _destroy($id){
global $_sess_db;
$id = mysql_real_escape_string($id);
$domain = mysql_real_escape_string(site_domain);
$agent = mysql_real_escape_string(isset($_SERVER['HTTP_USER_AGENT']));
$sql = "DELETE FROM sessions
WHERE id = '$id' AND domain = '$domain' AND agent = '$agent'";
return mysql_query($sql, $_sess_db);
}
function _clean($max){
global $_sess_db;
$old = time() - $max;
$old = mysql_real_escape_string($old);
$domain = mysql_real_escape_string(site_domain);
$agent = mysql_real_escape_string(isset($_SERVER['HTTP_USER_AGENT']));
$sql = "DELETE FROM sessions
WHERE access < '$old' AND domain = '$domain' AND agent = '$agent'";
return mysql_query($sql, $_sess_db);
}
? >
Ответ 12
Я прочитал все ответы выше, я думаю, что мой ответ полезен для людей, которые приходят в эту игру.
* Убедитесь, что браузеры отправляют cookie сеанса на серверы (домена и поддоменов), установите для домена cookie сеанса как ".example.com".
* Убедитесь, что php находит правильную "цель" для восстановления сеанса var
- Если домен и поддомены указывают на один и тот же компьютер (возможно, разные виртуальные хосты), убедитесь, что "session_save_path" одинаковый для всех (я тестировал)
- Если домен и поддомены указывают на разные машины, общее хранилище (например, база данных) лучше всего подходит для сохранения и восстановления данных сеанса (я еще не тестировал). Для этого используйте "session_set_save_handler".
Ответ 13
Просто попробуйте использовать следующий код чуть выше session_start()
method
$sess_life_time = 21600; //in seconds
$sess_path = "/";
$sess_domain = ".you-site-name.com";
$sess_secure = true; // if you have secured session
$sess_httponly = true; // httponly flag
session_set_cookie_params($sess_life_time, $sess_path, $sess_domain, $sess_secure, $sess_httponly);
Ответ 14
У меня была аналогичная проблема, однако это решение было полезно для меня, возможно, поможет другим в будущем
отредактируйте php.ini
session.cookie_domain = ".example.com"
волшебство здесь
suhosin.session.cryptdocroot = Off
suhosin.cookie.cryptdocroot = Off
https://www.sitepoint.com/community/t/sessions-across-subdomains-domain-com-phpsessid-changes/3013/19
Ответ 15
Я не могу говорить для других версий PHP, но в 5.6.6 просто установка значения session.cookie_domain
в файле php.ini
сделала трюк, чтобы разрешить всем моим поддоменам iPage использовать один и тот же набор переменные сеанса.
Обязательно удалите все существующие файлы cookie, относящиеся к вашему домену, из вашего браузера, чтобы проверить.
session.cookie_domain = '.yourdomainname.org'
О, не знаю, имеет ли это значение, но я также использую автозапуск сеанса.
session.auto_start = 1
Ответ 16
Пожалуйста, в моем случае у меня есть домен на сервере. Я создал субдомен подстановочных знаков, чтобы принимать любые субдомены. Теперь при попытке входа с поддоменом session_start отказывается зарегистрироваться. Я не мог получить доступ к данным сеанса. Что не так
Ответ 17
Быстрое и грязное решение - использовать это для вашей перенаправления:
header( $url.'?'.session_name().'='.session_id() );
это добавит что-то вдоль строки: PHPSESSID = etnm7kbuf5lg0r6tv7je6ehtn4 к URL-адресу, который сообщает PHP идентификатор сеанса, который он должен использовать.