2012-06-22 18 views
7

En nuestros sitios web queremos que sea posible compartir sesiones con varios dominios. Todos estos sitios web están en el mismo servidor, pero algunos de ellos tienen una dirección IP diferente.Cómo generar una ID de sesión única en php

La posible solución que encontré fue establecer el identificador de sesión a mí mismo:

<?php 
session_id($someUniqueHash); 
?> 

y esto funciona, si hago el hash MD5 como ('test'). En otro dominio en el mismo servidor, tenemos la sesión nuevamente.

El problema es generar la ID. Veo algunas soluciones en Internet con microtime, etc., pero cuando uso ese enfoque no puedo predecir el ID de sesión en el otro dominio/página PHP.

¿Alguien tiene una idea? ¿O no deberíamos implementar esto? ¿Hay otras opciones para compartir sesión en múltiples dominios? (NO subdominios!)

+1

¿Por qué no dejas que PHP genere la ID de la sesión por ti? Puede compartir ID de sesión entre dominios por cierto. Eso es una cuestión de la cookie * o * pasando un parámetro de consulta. – hakre

+0

El parámetro de consulta no se prefiere, es inseguro y no es amigable para las URL. Por lo que sé, solo permite que las cookies accedan al mismo dominio (también subdominios) que a los multidominios. –

+0

Es solo una cookie que pasa. Y puede crear cookies para dominios de terceros, las denominadas cookies de terceros. Es posible que también deba verificar el lado legal para hacer esto (al lado del aspecto técnico que está resuelto). Por cierto, todos los detalles técnicos es posible que desee conocer: [Mecanismo de gestión del estado HTTP RFC6265] (http://tools.ietf.org/html/rfc6265) – hakre

Respuesta

4

que he logrado este sistema mediante el uso de un flujo de OAuth tipo, pero que sustituyó al consumidor con el usuario.

De modo que cada dominio tendría el autenticado Access_Token en su propia sesión. Luego usaría Access_Token para obtener información sobre el usuario de una API.

También resolví el problema de sesión usando session_set_save_handler y almacenando sesiones en una tabla de base de datos ... Esta tabla también tendría Access_Token, lo que hace que sea muy fácil encontrar la sesión con una consulta de base de datos.

Espero que esto ayude con las ideas.

+0

He estado pensando en hacer esto últimamente. Me pregunto si hay algún estudio de caso o una simple discusión sobre el rendimiento de almacenamiento y recuperación al agregar el token de acceso en una tabla db y consultar cada solicitud. –

0

Hmm esto es difícil.

Como todos saben, PHP utiliza cookies para comprender session_ids cuando un usuario regresa a su sitio y no hay forma de cookies entre dominios: Cross domain cookies (edite: no existe pero el método es complicado).

Probablemente esta es la razón por la que nunca he visto un sitio implementar esto a pesar de que tienen diferentes dominios.

Puede, a través de un enlace en su página desde un dominio, pasar la identificación de la sesión al siguiente dominio a través de $ _GET o $ _POST. Esto no funcionará si el usuario ingresa directamente a su otro sitio.

El único método parcial (no confiable) que puedo idear es mantener un registro del comptuer de los usuarios en la base de datos y usarlo para entender a qué sesión está conectado. Así que guardas la dirección IP de la computadora y tal vez algunos otros detalles y eso respalda una sesión.

El IP y otros detalles de la computadora de una persona se registrarían en el otro dominio.

+0

Tnx. Hay un sitio web que lo hace: http://www.laptopshop.nl por ejemplo. Sé que su sitio web está desarrollado en PHP, por lo que es posible. Pero tenía miedo de que fuera difícil. –

+0

Corrijo mi respuesta Las cookies cruzadas son posibles pero sólidas como mencioné en esa publicación, pero sí las sesiones de dominios cruzados son realmente poco confiables ... – Sammaye

0

Quizás esta no sea una opción para usted, pero podría intentarlo.

En su sitio web principal de generar el identificador de sesión con normalidad y para perpetuar la sesión a otro dominio que podría incluir las etiquetas de imagen con el identificador de sesión en la URL. En respuesta, el otro dominio establecerá una cookie, por lo que cuando el visitante llega allí ya sabrá el id de sesión.

Se siente una solución un poco sabelotodo, pero debería funcionar si no tiene demasiados dominios :) Las cookies de terceros se pueden desactivar por separado en los navegadores por cierto, algo a considerar.

Oh, por cierto, la adopción de sesión (aceptar una identificación mediante parámetros de consulta y configurar una cookie) es algo delicado y debe protegerse, es decir, la sesión ya debe existir antes de establecer la cookie.

0

Configure cada sitio por separado:

<?php 

$cfgsession['file'] = "../sessions_global.txt"; 
$cfgsession['keepalive'] = 7200; 

?> 

Para hacer sesiones múltiples sitios de acción, vamos a usar el mismo $cfgsession['file']. Incluya una sesión de un sitio en una solicitud a otro dominio (tal como lo recomienda Jack), y siempre que no los encuentre haciendo su solicitud en otro navegador o lo que sea (haga algo para inhibir el secuestro de sesión) , permítales especificar una sesión con $ _GET. Por ejemplo:

include ("../session.php"); 
if (isset($_COOKIE['session'])) session_begin($_COOKIE['session'], $_SERVER['HTTP_USER_AGENT'] . "+" . $_SERVER['HTTP_ACCEPT_CHARSET'], $_SERVER['REMOTE_ADDR']); 
else session_begin("", $_SERVER['HTTP_USER_AGENT'] . "+" . $_SERVER['HTTP_ACCEPT_CHARSET'], $_SERVER['REMOTE_ADDR']); 
setcookie("session", session_identity(), 0); 

Y entonces acaba de rodar sus propias funciones session_:

<?php 

function session_begin($mysession = "", $key = "", $client = "") { 
    global $cfgsession; 
    if (!preg_match("/^[a-z0-9]{32}$/i", $mysession)) $mysession = md5(microtime()); 
    $error = false; 
    $client = trim($client); 
    $key = trim($key); 
    $cfgsession['returning'] = false; 
    if ($chandle = @tmpfile()) { 
    if ($shandle = @fopen($cfgsession['file'], "rb")) { 
     flock($shandle, LOCK_SH); 
     fputs($chandle, $mysession . " " . time() . " $" . $client . " $" . $key . "\n"); 
     while (!feof($shandle)) { 
     $sline = explode(" ", trim(fgets($shandle)), 4); 
     if ($sline[1] >= (time() - $cfgsession['keepalive'])) { 
      if (($sline[0] == $mysession) && ($sline[3] == "$" . $key)) { 
      $cfgsession['client'] = substr($sline[2], 1); 
      $cfgsession['returning'] = true; 
      } elseif (count($sline) > 2) fputs($chandle, implode(" ", $sline) . "\n"); 
     } 
     } 
     fclose($shandle); 
     fseek($chandle, 0); 
     if ($shandle = @fopen($cfgsession['file'], "cb")) { 
     if (flock($shandle, LOCK_EX)) { 
      ftruncate($shandle, 0); 
      $cfgsession['count'] = 0; 
      while (!feof($chandle)) { 
      $cline = trim(fgets($chandle)); 
      fputs($shandle, $cline . "\n"); 
      $cfgsession['count']++; 
      } 
     } else $error = true; 
     fclose($shandle); 
     } else $error = true; 
    } else $error = true; 
    fclose($chandle); 
    } else $error = true; 
    if (($cfgsession['returning'] == false) && ($mysession == $cfgsession['session'])) { 
    $cfgsession['returning'] = true; 
    $mysession = md5(microtime()); 
    } 
    $cfgsession['session'] = $mysession; 

    if ($error) return -1; 
    else return 0; 
} 

function session_count() { 
    global $cfgsession; 
    return $cfgsession['count']; 
} 

function session_client() { 
    global $cfgsession; 
    return $cfgsession['client']; 
} 

function session_id() { 
    global $cfgsession; 
    return $cfgsession['session']; 
} 

function session_index() { 
    global $cfgsession; 
    $index_return = array(); 
    if ($uhandle = @fopen($cfgsession['file'], "rb")) { 
    flock($uhandle, LOCK_SH); 
    while (!feof($uhandle)) { 
     $uline = explode(" ", trim(fgets($uhandle)), 4); 
     foreach ($uline as &$value) { 
     if ($value[0] == "$") $value = substr($value, 1); 
     } 
     if (count($uline) >= 2) $index_return[] = $uline; 
    } 
    fclose($uhandle); 
    } 
    return $index_return; 
} 

function session_returning() { 
    global $cfgsession; 
    return $cfgsession['returning']; 
} 

?> 
Cuestiones relacionadas