2011-01-21 30 views
6

Tôi nghe phương pháp tốt nhất để chia sẻ phiên trên nhiều tên miền trên cùng một máy chủ là sử dụng trình xử lý phiên php tùy chỉnh. (ví dụ, tên miền khác nhau như abc.com, xyz.com nhưng đơn đăng ký.)Chia sẻ phiên trên nhiều tên miền trên cùng một máy chủ

Nhưng sau khi tôi đã thử nó, ngay cả trình xử lý phiên php tùy chỉnh sử dụng cùng một DATABASE ON 1 SERVER không thể chia sẻ phiên, khi tôi đã thử để đọc giá trị cookie từ miền khác nhau.

Đây là trình xử lý phiên tùy chỉnh của tôi, Vui lòng kiểm tra hoặc khắc phục nếu thiếu thứ gì đó ở đây. vì tôi đã thử nó trong một tuần rồi. không thể làm cho nó hoạt động

P.S. Để có được id phiên trước, tôi sử dụng liên kết như: 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 Database Description

create table sess_data (
id2 int not null auto_increment, 
id text not null, 
data text, 
expire int not null, 
primary key(id2) 
); 
+0

tôi điều câu trả lời nằm ở đây: http://stackoverflow.com/questions/9317595/maintaining-session-variables-across-subdomains – haldyr

Trả lời

11

Bạn không thể đọc cookie từ một tên miền trong một tên miền khác. Đó là một điều bảo mật được thực hiện trong trình duyệt. Sử dụng cơ sở dữ liệu cho các phiên cho phép bạn có nhiều máy chủ chia sẻ phiên trên cùng một tên miền, nhưng không cho phép nhiều miền trên cùng một máy chủ chia sẻ phiên.

Nếu bạn muốn chia sẻ phiên giữa các tên miền, bạn sẽ cần triển khai một số loại phương thức chuyển phiên khi bạn chuyển đổi tên miền. Cách đơn giản nhất để làm điều này sẽ liên quan đến việc chuyển id phiên làm tham số GET từ một trang trên một tên miền sang trang khác. Sau đó, trên tên miền khác, bạn sẽ nhận id phiên và tạo phiên mới bằng ID đó.

Mặc dù đó là một cách đơn giản để thực hiện, nhưng nó không phải là rất an toàn và cho phép chiếm đoạt phiên. Cách tốt hơn là sử dụng cơ sở dữ liệu để tạo bản ghi với id phiên trong đó, đặt thời gian chờ ngắn trên đó và chuyển ID của bản ghi đó sang miền khác. Các tên miền khác sau đó sẽ lấy hồ sơ từ cơ sở dữ liệu và tạo một phiên với nó. Nếu bản ghi trong cơ sở dữ liệu đã hết hạn, nó sẽ không nhận phiên. Điều này sẽ cung cấp bảo vệ tốt hơn chống lại việc chiếm đoạt phiên.

+0

Nếu bạn muốn chia sẻ phiên giữa các lĩnh vực, bạn sẽ cần để thực hiện một số loại phương thức truyền phiên khi bạn chuyển đổi tên miền. vâng, tôi đã sử dụng phương pháp này để lấy id phiên trước .. nó không hoạt động .. nếu tên miền mới sử dụng cùng id, nó sẽ xóa id của miền trước –

+0

@Eric Petroelje, giải pháp của bạn rất tuyệt, Cảm ơn –

0

Bạn thực sự nên xem xét SSO (đăng nhập một lần). Một tùy chọn cho SSO là sử dụng OpenID (như được sử dụng trên SO) và việc sử dụng nó sẽ làm cho cuộc sống của bạn dễ dàng hơn nhiều.

Dưới đây là một bài viết về nó: http://devzone.zend.com/article/3581

0

cookie và tầm nhìn của họ là một vấn đề. Trình duyệt truy cập trang web mới sẽ không gửi id phiên của trang web cũ đến máy chủ.

Tôi nghĩ đọc của bạn() không sử dụng tham số ssid mà bạn cung cấp làm id phiên nhưng khi trình duyệt không có phiên nào với tên miền này, hệ thống sẽ tạo một phiên có id mới là $ id. Có một cái nhìn nếu $ _REQUEST ['ssid'] tồn tại trong cơ sở dữ liệu.

Trình xử lý phiên tùy chỉnh có thể hơi lớn đối với công việc này. Bạn chỉ có thể kiểm tra xem $ _REQUEST ['ssid'] tồn tại trong cơ sở dữ liệu phiên và viết lại $ _SESSION với nó hay không.

+0

xin lỗi, tôi nghĩ rằng vấn đề không phải là về id phiên đi qua đến tên miền mới .. bởi vì nó vẫn đang trong giai đoạn thử nghiệm tôi chỉ sử dụng addon firefox để tự thay đổi giá trị cookie của mình .. vì vậy không có vấn đề gì với việc truyền cookie! –

0

Tôi đã tự hỏi liệu có ai có thể đưa ra một số đề xuất về phương pháp chia sẻ phiên giữa các tên miền trên cùng một máy chủ (cùng một thư mục lưu trữ cookie) hay không.

Trong mỗi trang ĐẦU thẻ trên tất cả các trang web của tôi, tôi gọi là mã PHP sau

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'; 
} 

Sau đó, trên mỗi trang web tôi đã một tập tin gọi là 'sso_set.php' chứa

<?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'; 
    } 
} 

Có sử dụng liên kết văn bản/css hay không? Tôi nhận thấy điều này luôn được gọi ngay cả khi Javascript hoặc Hình ảnh bị tắt?

Mã này về cơ bản làm cho trang web đầu tiên ra khỏi tất cả các trang web của tôi được người dùng mở đặt ID phiên và sau đó chuyển nó đến các trang web khác.

Dường như hoạt động khá tốt. Bạn nhận được một chút chậm trễ lần đầu tiên bất kỳ trang web nào được mở và ID được chuyển đến các trang web. Tuy nhiên, bạn có thể thực hiện điều này thông qua AJAX để trang tải nhanh. Nhưng, sau đó bạn dựa vào Javascript đang được kích hoạt.

Suy nghĩ?

1

Đây là mục đích của session_name(). Chỉ định tên khác cho phiên của từng ứng dụng để tránh va chạm giữa các khóa $_SESSION. Tên sẽ được sử dụng làm tên của cookie phiên vì vậy mặc dù cả cookie phiên sẽ được chuyển đến cả hai ứng dụng, chỉ một cookie phù hợp với ứng dụng session_name() của bạn sẽ được sử dụng để điền $_SESSION.

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

// App 2 
session_name('app2'); 
session_start(); 
Các vấn đề liên quan