2011-01-21 9 views
6

Oí que el mejor método para compartir sesiones en varios dominios en el mismo servidor es utilizar el controlador de sesión php personalizado. (es decir, un nombre de dominio diferente como abc.com, xyz.com pero una sola aplicación.)Compartir sesión a través de múltiples dominios en el mismo servidor

Pero después de que lo intenté, incluso el gestor de sesión de php personalizado que usa SAME DATABASE ON 1 SERVER no puede compartir sesión, cuando probé para leer el valor de la cookie de diferentes dominios.

Aquí está mi gestor de sesión personalizado, compruebe o corrija amablemente si falta algo aquí. porque lo he intentado por una semana. no puede hacer que funcione

P.S. Para obtener id de sesión anterior, yo uso enlace tales como: 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(); 
?> 




base de datos MySQL Descripción

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

I cosa que la respuesta está aquí: http://stackoverflow.com/questions/9317595/maintaining-session-variables-across-subdomains – haldyr

Respuesta

11

No puede leer las cookies de un dominio en un otro dominio. Eso es algo de seguridad implementado en el navegador. El uso de una base de datos para sesiones le permite tener varios servidores compartiendo sesiones en el mismo dominio, pero no permite que varios dominios en el mismo servidor compartan sesiones.

Si desea compartir sesiones entre dominios, deberá implementar algún tipo de método de transferencia de sesión cuando cambie de dominio. La forma más sencilla de hacerlo sería pasar el ID de sesión como un parámetro GET de una página en un dominio a una página en el otro. Luego, en el otro dominio, recogerías la identificación de la sesión y crearías una nueva sesión usando esa ID.

Si bien esta es una forma sencilla de hacerlo, no es muy seguro y permite el secuestro de la sesión. Una forma mejor sería usar la base de datos para crear un registro con la ID de la sesión, establecer un tiempo de espera corto sobre ella y pasar el ID de ese registro al otro dominio. El otro dominio recogería el registro de la base de datos y crearía una sesión con él. Si el registro en la base de datos ha vencido su vencimiento, no retomará la sesión. Esto proporcionaría una mejor protección contra el secuestro de la sesión.

+0

Si desea compartir sesiones entre dominios, se necesitaría para implementar algún tipo de método de transferencia de sesión cuando cambias de dominio. sí, he usado este método para obtener la id de la sesión anterior ... no funciona ... si el nuevo dominio usa la misma identificación, eliminará la ID del dominio anterior –

+0

@Eric Petroelje, su solución es genial, gracias –

0

Realmente debería mirar en SSO (inicio de sesión único). Una opción para SSO es usar OpenID (como se usa en SO), y su uso hará que su vida sea mucho más fácil.

He aquí un artículo sobre ella: http://devzone.zend.com/article/3581

0

las galletas y su visibilidad es un problema. El navegador que acceda al nuevo sitio no enviará la identificación de sesión del sitio anterior al servidor.

Creo que su lectura() no utiliza el parámetro ssid que proporciona como id de sesión, pero como el navegador no tiene sesión con este dominio, el sistema genera uno con una nueva identificación como $ id. Eche un vistazo si $ _REQUEST ['ssid'] existe en la base de datos.

El controlador de sesión personalizado puede ser un poco grande para este trabajo. Solo podría verificar si $ _REQUEST ['ssid'] existe en la base de datos de sesión y volver a escribir $ _SESSION con él.

+0

lo siento, yo Creo que el problema no se trata de pasar la identificación de la sesión al nuevo dominio ... porque todavía está en fase de prueba. Solo uso firefox addon para cambiar manualmente el valor de la cookie. ¡Así que no hay problema con el paso de la cookie! –

0

Me preguntaba si alguien podría dar algunas sugerencias sobre mi método para compartir sesiones entre dominios en el mismo servidor (misma carpeta de almacenamiento de cookies).

En cada página cabeza etiqueta en todas mis sitios, que llamo el siguiente código 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'; 
} 

Luego, en cada sitio que tiene un archivo llamado 'sso_set.php' que contiene

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

¿Es una buena idea usar un enlace text/css? Pensé que esto siempre se llama incluso si Javascript o imágenes están deshabilitados?

Este código básicamente hace que el primer sitio de todos mis sitios que se abre por el usuario establezca la ID de sesión, y luego lo pasa a los otros sitios.

Parece que funciona bastante bien. Obtiene un ligero retraso la primera vez que se abre cualquiera de los sitios y se pasa el ID a los sitios. Pero, puedes hacer esto a través de AJAX para que la página se cargue rápido. Pero, entonces confías en que Javascript está habilitado.

¿Pensamientos?

1

Este es el propósito de session_name(). Asigne un nombre diferente a la sesión de cada aplicación para evitar colisiones entre las claves $_SESSION. El nombre se usará como el nombre de la cookie de sesión, de modo que aunque ambas cookies de sesión se pasarán a ambas aplicaciones, solo se usará el que coincida con el session_name() de la aplicación para completar $_SESSION.

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

// App 2 
session_name('app2'); 
session_start(); 
Cuestiones relacionadas