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"

но, похоже, он не передает информацию из одного домена в другой.

[Edit]

Я попробовал следующее:

sub1.domain.com/test.php

session_set_cookie_params(0, '/', '.domain.com');
session_start();
print session_id() . "<br>";
$_SESSION['Regsitered'] = 1;
echo '<a href="http://auth.domain.com/test.php">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, она не показывает оба ключа, а только тот ключ, который я установил в каждом домене.

[Edit 2]

Я обновил [Изменить]

 Milen A. Radev30 июн. 2009 г., 17:25
У меня почти такая же настройка (я установил домен cookie сеанса с вызовом "session_set_cookie_params"), и он отлично работает.
 boksiora14 июл. 2013 г., 11:25
Вот хорошая функция, которая работает / Stackoverflow.com вопросы / 2835486 / ...
 Residuum30 июн. 2009 г., 17:18
Вы также должны включить его в своем коде, см.http: //us2.php.net/manual/en/function.session-set-cookie-params.ph

Ответы на вопрос(16)

существует ли проблема до сих пор, но я столкнулся с той же самой проблемой и решил ее, установив имя сеанса перед вызовом session_set_cookie_params ():

$some_name = session_name("some_name");
session_set_cookie_params(0, '/', '.some_domain.com');
session_start();

Я ничего не изменил в своем php.ini, но теперь все работает нормально.

 Kit17 мар. 2011 г., 13:19
Прекрасно работает! Искал для этого целую вечность. Это было$some_name = session_name("some_name"); это сделал. Спасибо и upvote.
 Roman10 февр. 2011 г., 18:04
Я подтверждаю, это решает проблему. Я устал, чтобы получить свой ответ там: / Stackoverflow.com вопросы / 4948340 / .... Но я нашел это здесь.
 Anupam05 мая 2013 г., 18:47
работал как шарм, спасибо
 Daithí15 янв. 2012 г., 21:46
Ага. подтверждено. хороший там ходил кругами целую вечность;)
 David Carroll03 июл. 2011 г., 09:28
Добавлениеsession_name("domain"); был недостающим ингредиентом и для меня. Документация на php.net относительно этих настроек сеанса отсутствует. На php.net есть сообщения сообщества, в которых указано, что для определения изменений session.set_cookie_params () необходимо указать session.name.

Используйте его на каждом домене / поддомене:

session_name('name');
ini_set('session.cookie_domain', '.example.com');
ini_set('session.save_path', '/var/lib/php/session');
session_start();

Путь дляsession.save_path может отличаться для вашего случая, но это должно бытьодно и тож на каждом домене / поддомене. Это не всегда верно по умолчанию.

 Kamal Kumar04 июл. 2016 г., 12:34
работает идеально для меня, спасибо

что вам не нужно что-то вроде OpenID, как предлагает Джоэл, но вы хотите иметь доступ к данным сеанса в нескольких доменах.

Единственная возможность, которую я могу представить как решение этой проблемы, - это сохранить данные сеанса в базе данных и извлечь их из этой базы данных.

 dragonmantank30 июн. 2009 г., 20:47
Правильно, хотя аутентификация является частью того, что я хочу сделать, меня также интересуют данные сеанса, которые сохраняются во время работы пользователя.

session.cookie_domain значение вphp.ini file позволил всем моим поддоменам на iPage использовать один и тот же набор переменных сеанса.

Обязательно удалите из браузера все существующие файлы cookie, связанные с вашим доменом, для тестирования.

session.cookie_domain = '.yourdomainname.org'

Не знаю, имеет ли это какое-то значение, но я также использую автозапуск сеанса.

session.auto_start = 1

Попробуйте использовать:

session.cookie_domain = "domain.com"

Вместо того

session.cookie_domain = ".domain.com"

Отметьте пропущенный период.

Будьте осторожны, используя это, потому что это поддерживается не всеми браузерами.

 Kuf20 окт. 2014 г., 19:45
Какая поддержка браузера должна быть здесь? это действие на стороне сервера.
 gawpertron16 февр. 2011 г., 20:09
Какие браузеры не поддерживаются?

которая может таинственным образом предотвратить чтение данных сеанса на поддомене, несмотря на то, что куки правильно установлены на.domain.com - это исправление PHP Suhosin. Вы можете настроить все правильно, как показано в примерах в вопросе, и это может просто не работать.

Отключите следующие настройки сеанса Suhosin, и вы снова в деле:

suhosin.session.cryptua = Off 
suhosin.session.cryptdocroot = Off

header( $url.'?'.session_name().'='.session_id() );

this добавит что-то вроде? PHPSESSID = etnm7kbuf5lg0r6tv7je6ehtn4 к URL, что говорит PHP идентификатор сеанса, который он должен использовать.

 Bastiaan ten Klooster09 окт. 2017 г., 11:33
Это менее безопасно в том смысле, что пользователи могут (обмануть) поделиться своими URL-адресами и, таким образом, поделиться своими активными идентификаторами сеансов. Гораздо менее вероятно, что пользователь поделится своим файлом cookie идентификатора сессии невольно.
 dragonmantank30 июн. 2009 г., 21:08
Это также делает его очень уязвимым для кражи сессии :) Проблема не в том, что идентификаторы сессии не совпадают (они есть, смотрите мой обновленный пост), а в том, что данные не перемещаются между доменам
 Ian Jamieson18 февр. 2013 г., 11:02
Согласитесь, это очень уязвимо, оставляя идентификатор сессии в строке запроса.
 sakabako01 мар. 2013 г., 20:48
Cookies также отправляются в виде простого текста, это не открывает никаких путей, которые еще не были открыты. Я не говорю, что это хорошее решение, но оно не менее безопасно, чем использование файлов cookie.

Я решил это так

ini_set('session.cookie_domain', '.testdomain.dev');
session_start();

Потому что я работал на localhost

ini_set('session.cookie_domain', '.localhost');

не работал, он видит .localhost как верхний уровень вместо .com / .local / ... (я подозреваю)

Я также использовал .dev, потому что работа над OS X, похоже, не разрешает .com как первое в HOSTS

 dennis01 февр. 2015 г., 11:41
Также исправил это для моей машины - Ubuntu 14.04

Просто попробуйте использовать следующий код чуть вышеsession_start() метод

$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);

чтобы значения сеанса, созданные на x.example.local, были доступны на example.local и наоборот.

Все решения, которые я нашел, сказали, чтобы изменить домен Session с помощьюphp_value session.cookie_domain .example.local в .htaccess (или через php.ini или через ini_set).

Улов был, я устанавливалsession.cookie_domain для всех поддоменов (пока что все в порядке), но также и для основного домена. Установкаsession.cookie_domain в основном домене, по-видимому, нет-нет.

В основном, как это работает для меня:

установитьsession.cookie_domain для ВСЕХ СУБДОМЕНОВ. не устанавливай его для основного домена

Да, пожалуйста, убедитесь, что домен имеет TLD (в моем случае .local). Протокол Http не позволяет сохранять файлы cookie / сеансы в домене без .tld (т. Е. Localhost не будет работать, но будет работать stuff.localhost).

РЕДАКТИРОВАТ: Также убедитесь, что вы всегда удаляете куки-файлы своего браузера при тестировании / отладке сессий на поддоменах Если вы этого не сделаете, ваш браузер всегда будет отправлять старый файл cookie сеанса, который, вероятно, еще не установил правильный cookie_domain. Сервер восстановит старый сеанс, и поэтому вы получите ложноотрицательные результаты. (во многих сообщениях упоминается использование session_name ('stuff') для точно такого же эффекта)

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

Используйте это, это работает:

ini_set('session.cookie_domain', 
    substr($_SERVER['SERVER_NAME'],strpos($_SERVER['SERVER_NAME'],"."),100));
 chacham1521 янв. 2015 г., 00:58
это похоже на то, что он устанавливает cookie для tld ... или я что-то упустил?

я

Ресурс:http: //php.net//manual/tr/function.session-set-cookie-params.ph

Я тестировал работы

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); 
?>

что это старая версия, но она отлично работает для меня с несколькими доменами и поддоменами в одной коробке.

<?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', '$a,gent')";

    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);

}

?>

 cale_b28 окт. 2012 г., 22:20
На какой вопрос ты отвечаешь? И как это улучшает / улучшает 9 других ответов?

я думаю, что мой ответ полезен для людей, гуглящих это.

* Убедитесь, что браузеры отправляют файл cookie сеанса обратно на серверы (домена и поддоменов), установите домен файла cookie сеанса как «.example.com».

* Убедитесь, что php находит правильную «цель» для восстановления сеанса var - Если домен и дочерние домены указывают на одну и ту же машину (возможно, разные виртуальные хосты), убедитесь, что «session_save_path» одинаков для всех (я проверял) - Если домен и поддоменов указывают на разные машины, общее хранилище (например, база данных) лучше всего подходит для сохранения и восстановления данных сеанса (я еще не тестировал). Используйте "session_set_save_handler", чтобы сделать это.

однако, это решение было хорошо для меня, возможно, поможет другим в будущем

edit 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/1

Ваш ответ на вопрос