2011-01-21 2 views
6

동일한 서버의 여러 도메인에서 세션을 공유하는 가장 좋은 방법은 맞춤 PHP 세션 처리기를 사용하는 것입니다. (즉, abc.com, xyz.com과 같은 도메인 이름은 하나의 응용 프로그램입니다.)동일한 서버의 여러 도메인에서 세션 공유

그러나 내가 시도한 후에도 사용자 지정 PHP 세션 처리기에서 동일한 데이터베이스를 사용하는 서버가 세션을 공유 할 수 없습니다. 다른 도메인에서 쿠키 값을 읽는 중입니다.

여기 내 맞춤 세션 처리기입니다. 여기에 누락 된 항목이 있으면 확인하거나 수정하십시오. 왜냐하면 나는 일주일 동안 그것을 시도했기 때문입니다. 그것을 작동시킬 수 없다.

P. 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

하나의 도메인에서 쿠키를 읽을 수 없습니다. 다른 도메인. 브라우저에 구현 된 보안 기능입니다. 세션 용 데이터베이스를 사용하면 여러 서버가 동일한 도메인에서 세션을 공유하도록 할 수 있지만 동일한 서버의 여러 도메인이 세션을 공유하는 것을 허용하지 않습니다.

도메인간에 세션을 공유하려면 도메인을 전환 할 때 몇 가지 종류의 세션 전송 방법을 구현해야합니다. 가장 간단한 방법은 세션 ID를 GET 매개 변수로 한 도메인의 페이지에서 다른 페이지의 페이지로 전달하는 것입니다. 그런 다음 다른 도메인에서 세션 ID를 선택하고 해당 ID를 사용하여 새 세션을 만듭니다.

간단한 방법이지만 안전한 것은 아니며 세션 도용을 허용합니다. 더 좋은 방법은 데이터베이스를 사용하여 세션 ID가 포함 된 레코드를 만들고 세션에 짧은 시간 제한을 설정하고 해당 레코드의 ID를 다른 도메인에 전달하는 것입니다. 다른 도메인은 데이터베이스에서 레코드를 선택하여 세션을 생성합니다. 데이터베이스의 레코드가 만기가 지난 경우 세션을 선택하지 않습니다. 이렇게하면 세션 도용에 대한 보호 기능이 향상됩니다.

+0

당신이 도메인간에 세션을 공유하려는 경우, 당신이 필요로하는 것 도메인을 전환 할 때 일종의 세션 전송 방법을 구현합니다. 예, 이전 세션 ID를 얻기 위해이 방법을 사용했습니다 .. 새로운 도메인이 동일한 ID를 사용하면 이전 도메인의 ID를 삭제합니다 –

+0

@Eric Petroelje, 솔루션은 훌륭합니다, 감사합니다. –

0

정말 SSO (Single Sign-On)를 조사해야합니다. SSO에 대한 한 가지 옵션은 OpenID (SO에서 사용 된 것과 같이)를 사용하는 것입니다.이 옵션을 사용하면 삶이 훨씬 쉬워 질 것입니다. http://devzone.zend.com/article/3581

0

쿠키 및 가시성 문제입니다 :

는 여기에 기사입니다. 새 사이트에 액세스하는 브라우저는 이전 사이트의 세션 ID를 서버에 보내지 않습니다.

귀하의 read()는 세션 ID로 제공 한 ssid 매개 변수를 사용하지 않지만 브라우저가이 도메인과 세션이 없으므로 시스템은 $ id와 같은 새로운 ID를 가진 세션을 생성합니다. $ _REQUEST [ 'ssid']가 데이터베이스에 있는지 살펴보십시오.

사용자 지정 세션 처리기가이 작업에 약간 클 수 있습니다. 세션 데이터베이스에 $ _REQUEST [ 'ssid']가 있는지 확인하고 $ _SESSION을 다시 작성하면됩니다.

+0

죄송합니다. 문제는 새로운 도메인에 세션 ID를 전달하는 문제가 아니라고 생각합니다. 테스트 단계에 있기 때문에 나는 수동으로 파이어 폭스 애드온을 사용하여 수동으로 쿠키 값을 변경합니다. 따라서 쿠키 전달에 문제가 없습니다! –

0

같은 서버 (동일한 쿠키 저장소 폴더)에있는 도메인간에 세션을 공유하는 방법에 대한 제안을 누군가가 줄 수 있는지 궁금합니다.각 페이지에서

나는 다음과 같은 PHP 코드를 호출, 내 모든 사이트에 태그를 HEAD

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 
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'불렀다 텍스트/CSS 링크를 사용하고 계신가요? Javascript 또는 이미지가 비활성화 된 경우에도 항상 호출되는 것으로 생각하십니까?

이 코드는 기본적으로 사용자가 열어 본 내 모든 사이트에서 첫 번째 사이트를 만들어 세션 ID를 설정 한 다음 다른 사이트로 전달합니다.

꽤 잘 작동하는 것 같습니다. 사이트를 처음 열었을 때 약간의 지연이 발생하고 ID가 사이트로 전달됩니다. 그러나 AJAX를 통해이 작업을 수행 할 수 있으므로 페이지가 빠르게로드됩니다. 하지만 자바 스크립트가 활성화되어 있어야합니다.

생각하십니까?

1

이것은 session_name()의 목적입니다. $_SESSION 키 사이의 충돌을 피하려면 각 응용 프로그램의 세션에 다른 이름을 지정하십시오. 이름은 세션 쿠키 이름으로 사용되므로 두 세션 쿠키가 두 응용 프로그램에 모두 전달되지만 응용 프로그램의 session_name()과 일치하는 쿠키 만 사용하여 $_SESSION을 채 웁니다.

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

// App 2 
session_name('app2'); 
session_start(); 
관련 문제