web-dev-qa-db-ja.com

PHPサブドメイン間のセッション

私は次を設定しようとしています:

auth.example.com
sub1.example.com
sub2.example.com

ユーザーがsub1.example.comまたはsub2.example.comにアクセスし、ログインしていない場合、ユーザーはauth.example.comにリダイレクトされてログインできます。

sub1.example.comsub2.example.comは2つの別個のアプリケーションですが、同じ資格情報を使用します。

私はphp.iniで以下を設定しようとしました:

session.cookie_domain = ".example.com"

しかし、あるドメインから別のドメインに情報を渡すようには見えません。

[編集]

私は次を試しました:

sub1.example.com/test.php

session_set_cookie_params(0, '/', '.example.com');
session_start();
print session_id() . "<br>";
$_SESSION['Regsitered'] = 1;
echo '<a href="http://auth.example.com/test.php">Change Sites</a>'

auth.example.com/test.php

session_set_cookie_params(0, '/', '.example.com');
session_start();
print session_id() . "<br>";
$_SESSION['Checked'] = 1;
print_r($_SESSION);

セッションIDはまったく同じですが、$_SESSION変数をダンプすると、両方のキーが表示されず、各ドメインで設定したキーだけが表示されます。

88
dragonmantank

問題がまだ存在するかどうかはわかりませんが、同じ問題にぶつかり、session_set_cookie_params()を呼び出す前にセッション名を設定して解決しました。

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

私はphp.iniしかし、今ではすべてがうまく機能しています。

129
jeroen

Cookieが.example.comはPHP Suhosinパッチです。質問の例のように、すべてを正しく構成することができますが、機能しません。

次のSuhosinセッション設定をオフにすると、ビジネスに戻ります。

suhosin.session.cryptua = Off 
suhosin.session.cryptdocroot = Off
24
drewm

使用してみてください:

session.cookie_domain = "example.com"

の代わりに:

session.cookie_domain = ".example.com"

開始時に欠落している期間に注意してください。

ただし、これはすべてのブラウザでサポートされているわけではないため、使用には注意してください。

5
George Claghorn

この正確な問題があった-x.example.localで作成されたセッション値をexample.localで利用可能にしたい、またはその逆をしたかった。

私が見つけたすべてのソリューションは、.htaccessでphp_value session.cookie_domain .example.localを使用して(またはphp.iniまたはini_setを介して)Sessionドメインを変更すると述べました。

問題は、session.cookie_domainをすべてのサブドメイン(これまでのところ問題ありません)だけでなく、メインドメインにも設定していたことです。メインドメインでsession.cookie_domainを設定することは、明らかにいいえです。

基本的にそれが私のために働いた方法:

  • すべてのサブドメインにsession.cookie_domainを設定します。
  • メインドメインには設定しないでください

そうそう、ドメインにTLD(私の場合は.local)があることを確認してください。 Httpプロトコルでは、.tldなしでCookie /セッションをドメインに保存することはできません(つまり、localhostは機能しませんが、stuff.localhostは機能します)。

[〜#〜] edit [〜#〜]:また、サブドメイン間でセッションをテスト/デバッグする際は、常にブラウザのCookieをクリアしてください。そうしないと、ブラウザは常に正しいcookie_domainがまだ設定されていない古いセッションCookieを常に送信します。サーバーは古いセッションを復活させるため、偽陰性の結果が得られます。 (多くの投稿で、まったく同じ効果のためにsession_name( 'stuff')を使用することが言及されています)

4
Valentin Florea

このように解決しました

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

Localhostで作業していたので

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

動作していませんでした 、. com/.local/...ではなく.localhostをトップレベルとして認識します(疑わしい)

3
xtds

確認しました。 joreonの答えは正しいです。評判が足りないのでコメントできませんので、ここにコメントを投稿します。

構成ファイルで定数を定義します。変更する場合は、ファイル全体を変更する必要はありません。

define('ROOT_DOMAIN',   'mysite.example');
define('PHP_SESSION_NAME', 'MYSITE'); 

セッション名は数字のみで構成することはできません。少なくとも1つの文字が必要です。それ以外の場合は、新しいセッションIDが毎回生成されます。

次のコードを使用して、セッションの使用を開始します

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
2
Terry Lin

すべてのドメイン/サブドメインで使用します:

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

session.save_pathのパスはケースによって異なる場合がありますが、すべてのドメイン/サブドメインで同じにする必要があります。デフォルトでは常に正しいとは限りません。

2

これを使用して、動作します:

ini_set('session.cookie_domain', 
    substr($_SERVER['SERVER_NAME'],strpos($_SERVER['SERVER_NAME'],"."),100));
1
Ivan

サブドメインとルートドメインのCookieセッションの併用

リソース: http://php.net//manual/tr/function.session-set-cookie-params.php

私は作品をテストしました

sub.example.com/sessionadd.php?id=123

example.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); 
?>
1
Limitless isa

上記のすべての答えを読みましたが、私の答えはこれをグーグルの人々に役立つと思います:

  • ブラウザが(ドメインおよびサブドメインの)サーバーにセッションCookieを送り返すことを確認し、セッションCookieドメインを.example.com

  • PHPセッション変数を復元する正しい「ターゲット」を見つけてください:

    • ドメインとサブドメインが同じマシン(異なる仮想ホストの場合もある)を指している場合は、session_save_pathはすべて同じ(テスト済み)
    • ドメインとサブドメインが異なるマシンを指している場合、共通ストレージ(データベースなど)がセッションデータの保存と復元に最適です(まだテストしていません)。つかいます session_set_save_handlerそれを行う。
0
user953985

Joelが提案しているように、OpenIDのようなものは必要ないが、複数のドメインにわたるセッションデータにアクセスしたいという考えがあります。

私がその問題の解決策と考えることができる唯一の可能性は、セッションデータをデータベースに保存し、そのデータベースからそれを引き出すことです。

0
Thomas

私はこれが古いことを知っていますが、同じボックスに複数のドメインとサブドメインがある場合、これはうまく機能します。

<?php
define('site_domain','example.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);

}

?>

0
Ian

私は同様の問題を抱えていましたが、この解決策は私にとって良いものでした。おそらく他の人にも役立つでしょう

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

0
Willian Santana

session_start()メソッドのすぐ上の次のコードを使用してみてください

$sess_life_time = 21600; //in seconds
$sess_path = "/";
$sess_domain = ".example.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);
0
mohsin.mr

PHPの他のバージョンについて話すことはできませんが、5.6.6では、単にsession.cookie_domainの値php.iniファイルは、iPage上のすべてのサブドメインが同じセッション変数のセットを共有できるようにするトリックを行いました。

ドメインに関連する既存のCookieをブラウザから削除して、テストしてください。

session.cookie_domain = '.yourdomainname.example'

ああ、違いがあるかどうかわかりませんが、セッションの自動開始も使用しています。

session.auto_start = 1
0
user3232196