2011-01-21 38 views
6

同じサーバー上の複数のドメイン間でセッションを共有する最善の方法は、カスタムPHPセッションハンドラを使用することです。 (すなわちabc.com、xyz.comのように異なるドメイン名ですが、単一のアプリケーションです)同じサーバー上の複数のドメイン間でのセッション共有

しかし、試してみたところ、同じデータベースを使用しているカスタムPHPセッションハンドラもセッションを共有できませんでした。別のドメインからCookieの値を読み取る

ここに私のカスタムセッションハンドラがあります。ここに欠けているものがあるかどうかチェックしてください。私は今一週間それを試したので。それを働かせることができない

P.S. newdomain.com/?ssid=[SESSION_ID]


SESSION_INCLUDE.PHP

<?php 

// config 
$m_host = "localhost"; //MySQL Host 
$m_user = "db_user"; //MySQL User 
$m_pass = "db_pass"; //MySQL Pass 
$m_db = "db_name"; //MySQL Database 
$table = "sess_data"; 

$session_expire = 600; // Session expire time, in seconds (minutes * 60 = seconds) 

$gc_probability = 100; // Probability that the garbage collection function will be called. 50% chance by default 

ini_set("session.gc_probability",$gc_probability); 

/* Open function; Opens/starts session 

    Opens a connection to the database and stays open until specifically closed 
    This function is called first and with each page load */ 

function open ($s,$n) // do not modify function parameters 
{ 
    global $session_connection, $m_host, $m_user, $m_pass, $m_db; 
    $session_connection = mysql_pconnect($m_host,$m_user,$m_pass); 
    mysql_select_db($m_db,$session_connection); 
    return true; 
} 

/* Read function; downloads data from repository to current session 

    Queries the mysql database, unencrypts data, and returns it. 
    This function is called after 'open' with each page load. */ 
function read ($id) // do not modify function parameters 
{ 
    global $session_connection,$session_read,$table; 
    $query = "SELECT data FROM `$table` WHERE id=\"{$id}\""; 
    $res = mysql_query($query,$session_connection); 
    if(mysql_num_rows($res) != 1) return ""; // must return string, not 'false' 
    else 
    { 
    $session_read = mysql_fetch_assoc($res); 
    $session_read["data"] = base64_decode($session_read["data"]); 
    return $session_read["data"]; 
    } 
} 
function write ($id,$data) // do not modify function parameters 
{ 
    if(!$data) { return false; } 
    global $session_connection, $session_read, $session_expire, $table; 
    $expire = time() + $session_expire; 
    $data = mysql_real_escape_string(base64_encode($data)); 
    if($session_read) $query = "UPDATE `$table` SET data=\"{$data}\", expire=\"{$expire}\" WHERE id=\"{$id}\""; 
    else $query = "INSERT INTO sess_data SET id=\"{$id}\", data=\"{$data}\", expire=\"{$expire}\""; 
    mysql_query($query,$session_connection); 
    return true; 
} 
function close() 
{ 
    global $session_connection; 
    mysql_close($session_connection); 
    return true; 
} 
function destroy ($id) // do not modify function parameters 
{ 
    global $session_connection,$table; 
    $query = "DELETE FROM `$table` WHERE id=\"{$id}\""; 
    mysql_query($query,$session_connection); 
    return true; 
} 
function gc ($expire) 
{ 
    global $session_connection,$table; 
    $query = "DELETE FROM `$table` WHERE expire < ".time(); 
    mysql_query($query,$session_connection); 
} 
// Set custom handlers 
session_set_save_handler ("open", "close", "read", "write", "destroy", "gc"); 

// Start session 
session_start(); 
?> 




MySQLのデータベース説明

:前回のセッションIDを取得するには、私のようなリンクを使用します
create table sess_data (
id2 int not null auto_increment, 
id text not null, 
data text, 
expire int not null, 
primary key(id2) 
); 
+0

私の事: http://stackoverflow.com/questions/9317595/maintaining-session-variables-across-subdomains – haldyr

答えて

11

1つのドメインのCookieを他のドメイン。それはブラウザに実装されたセキュリティです。セッション用のデータベースを使用すると、複数のサーバーで同じドメイン上のセッションを共有できますが、同じサーバー上の複数のドメインでセッションを共有することはできません。

ドメイン間でセッションを共有する場合は、ドメインを切り替えるときに、ある種のセッション転送方法を実装する必要があります。これを行う最も簡単な方法は、セッションIDをGETパラメータとしてあるドメインのページから別のドメインのページに渡すことです。次に、他のドメインでは、セッションIDを取得し、そのIDを使用して新しいセッションを作成します。

これは簡単な方法ですが、あまり安全ではなく、セッションのハイジャックが可能です。より良い方法は、データベースを使用してセッションIDを持つレコードを作成し、それに短いタイムアウトを設定し、そのレコードのIDを他のドメインに渡すことです。他のドメインは、データベースからレコードを取得し、それとセッションを作成します。データベースのレコードが有効期限を過ぎている場合は、セッションを取得しません。これにより、セッションハイジャックに対するより良い保護が提供されます。

+0

あなたがドメイン間でセッションを共有したい場合は、あなたが必要になりますドメインを切り替えるときに何らかの種類のセッション転送方法を実装するはい、以前のセッションIDを取得するためにこのメソッドを使用しました..新しいドメインが同じIDを使用する場合、以前のドメインのIDを削除します –

+0

@Eric Petroelje、あなたの解決策は素晴らしいです、 –

0

本当にSSO(シングルサインオン)を調べる必要があります。 SSOの1つの選択肢は、OpenIDを(SOに使用されているように)使用することです。これを使用すると、あなたの人生が楽になります。ここで

はそれについての記事です:http://devzone.zend.com/article/3581

0

クッキーとその可視性は問題です。新しいサイトにアクセスするブラウザは、古いサイトのセッションIDをサーバーに送信しません。

私は、セッションIDとして提供するssidパラメータを使用しませんが、ブラウザがこのドメインとのセッションを持たないため、システムは$ idとして新しいIDを持つセッションを生成します。 $ _REQUEST ['ssid']がデータベースに存在するかどうか調べてください。

このジョブではカスタムセッションハンドラが少し大きいかもしれません。セッションデータベースに$ _REQUEST ['ssid']が存在するかどうかを確認して$ _SESSIONを書き直すことができます。

+0

問題は、新しいドメインにセッションIDを渡すことではないと思う。それはテスト段階にあるので、私はただ手動でFirefoxのアドオンを使って手動でCookieの値を変更する。 –

0

誰かが同じサーバー(同じCookieストレージフォルダ)のドメイン間でセッションを共有する方法についていくつか提案することができるのだろうかと思っていました。すべての私のサイトの各ページのHEADタグで

、私は

<?php 
session_start(); 
if(!isset($_SESSION['sso'])) { 
    require_once('database.php'); 
    $key = $_GET['k']; 
    $session_id = $database->getSessionId($key); 
    if($session_id) { 
     session_destroy(); 
     session_id($session_id); 
     session_start(); 
     $database->deleteSessionId($key); 
     $_SESSION['sso'] = 'SET'; 
    } 
} 

が含まれている「sso_set.php」と呼ばれるファイルを持っている各サイトで次に

if(!isset($_SESSION['sso'])) { 
    require_once('database.php'); 
    $sites = array('http://site1', 'http://site2'); 
    session_regenerate_id(); //Make new session id that will be shared 

    $session_id = session_id(); 
    foreach($sites as $site) { 
     if($site != CURRENT_SITE) { 
      $sesh_key = md5(SALT.$site.$session_id); 
      $database->insertSessionId($sesh_key, $session_id); 
      $url = sprintf('%s/sso_set.php?k=%s', $site, $sesh_key); 
      echo('<link type="text/css" rel="stylesheet" href="'.$url.'" />'); 
     } 
    } 
    $_SESSION['sso'] = 'SET'; 
} 

次のPHPコードを呼び出しますテキスト/ CSSのリンクを使用していますか? JavascriptやImagesが無効になっていても、これは常に呼び出されると思いましたか?

このコードは、基本的に、ユーザーが開いたすべての自分のサイトのうち最初のサイトをセッションIDを設定し、それを他のサイトに渡します。

かなりうまくいくと思われます。 サイトが開かれ、そのIDがサイトに渡されたのは初めてです。しかし、あなたはAJAX経由でこれを行うことができるので、ページは高速に読み込まれます。しかし、その後、Javascriptが有効になっていることに依存します。

思考?

1

これはsession_name()の目的です。 $_SESSIONキー間の衝突を避けるために、各アプリケーションのセッションに異なる名前を割り当てます。名前はセッションCookieの名前として使用されるため、両方のセッションCookieは両方のアプリケーションに渡されますが、アプリケーションのsession_name()に一致するもののみが$_SESSIONの入力に使用されます。答えはここにある

// App 1 
session_name('app1'); 
session_start(); 

// App 2 
session_name('app2'); 
session_start(); 
関連する問題