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


92

以下を設定しようとしています:

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

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

sub1.example.com そして sub2.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変数をダンプすると、両方のキーが表示されず、各ドメインで設定したキーだけが表示されます。


あなたはあなたのコードでそれを可能にするだけでなく、見なければならないhttp://us2.php.net/manual/en/function.session-set-cookie-params.phpを

1
私はほとんど同じ設定をして( "session_set_cookie_params"を呼び出してセッションCookieドメインを設定しました)、それはうまくいきます。
Milen A. Radev

回答:


134

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

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

私は何も変更してphp.iniいませんが、今はすべて正常に動作しています。


10
問題は解決しました。私はそこで答えを得るのに疲れました:stackoverflow.com/questions/4948340/…。しかし、私はそれをここで見つけました。
ローマ

5
完璧に動作します!このための年齢を探してきました。$some_name = session_name("some_name");やったのはそれだった。ありがとうございました。
キット

4
追加することsession_name("domain");も、私にとって欠けている成分でした。これらのセッション設定に関するphp.netのドキュメントが不足しています。php.netには、session_set_cookie_params()への変更を適用する前にsession.nameを定義する必要があることを示すコミュニティの投稿があります。
David Carroll

3
うん。確認した。素敵なのは、年齢を重ねて周回していた;)
DaithíJan

1
注...ライフサーバーで動作させるには、ブラウザを閉じて再起動する必要がありました。ini_set("session.cookie_domain", ".domain.com");更新のたびに新しいセッションIDが作成される原因となった原因を除外します。
Daithí

24

Cookieが正しく設定されているにもかかわらず、セッションデータがサブドメインで読み取られることを不可解に防止できる1つのこと.example.comは、PHP Suhosinパッチです。問題の例に従って、すべてを正しく構成することができますが、それは機能しません。

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

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

5

使ってみてください:

session.cookie_domain = "example.com"

の代わりに:

session.cookie_domain = ".example.com"

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

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


9
サポートされていないブラウザはどれですか?
gawpertron、2011

10
ここまでのブラウザのサポートは何ですか?これはサーバー側のアクションです。
Kuf

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すべてのサブドメインにを設定します。
  • メインのドメインには設定しないでください

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

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


3

このように解決しました

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

私はlocalhostで作業していたので

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

うまくいかなかった、それは.com / .local /の代わりに.localhostをトップレベルとして見る...(私は疑う)


私のマシンでも修正されました
-Ubuntu

3

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

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

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();
    } elseif (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

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

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

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


1

これを使用してください、それは動作します:

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

これは、TLDのCookieの設定のように見えます...または何か不足していますか?
chacham15 2015年

1

サブドメインとルートドメインの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); 
?>

0

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

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


そうです、認証は私がやりたいことの一部ですが、ユーザーが作業している間に保存されるセッションデータにも興味があります。
dragonmantank


0

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

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

session.cookie_domain = '.yourdomainname.example'

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

session.auto_start = 1

0

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

上記のすべての回答を読みました。私の回答は、これをグーグルする人々に役立ちます。

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

  • PHPがセッション変数を復元するための適切な「ターゲット」を見つけていることを確認してください。

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

0

これは古いことはわかっていますが、同じボックスに複数のドメインとサブドメインがある場合は、これでうまくいきます。

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

}

?>


6
どんな質問に答えますか?そして、これは他の9つの答えをどのように改善/強化しますか?
random_user_name 2012年


-2

迅速で汚い解決策は、リダイレクトにこれを使用することです:

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

これにより、の行に沿って何かが追加さ?PHPSESSID=etnm7kbuf5lg0r6tv7je6ehtn4れ、PHPに使用するセッションIDが通知されます。


3
また、セッションの盗難に対して非常に脆弱です:)問題は、セッションIDが一致しないこと(それらは一致する、私の更新された投稿を参照)ではなく、データがドメイン間で移動しないことです。
dragonmantank

同意されたとおり、これは非常に脆弱であり、クエリ文字列にセッションIDを残します。
イアンジェイミソン2013

4
Cookieもプレーンテキストで送信されます。これにより、まだ開かれていない手段は開かれません。それが良い解決策であると言っているわけではありませんが、クッキーを使用するよりも安全です。
sakabako 2013年

1
ユーザーが自分のURLを(だまされて)共有し、アクティブなセッションIDを共有する可能性があるという意味では、安全性は低くなります。ユーザーがセッションID Cookieを無意識に共有する可能性ははるかに低くなります。
バスティアンテンクルースター2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.