Сеансы 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);

Ответ 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 идентификатор сеанса, который он должен использовать.