2012-06-22 86 views
7

在我们的网站上,我们希望能够共享会话accros多个域。所有这些网站都在同一台服务器上,但其中一些具有不同的IP地址。如何在php中生成唯一的会话ID

可能的解决方案,我发现是设置会话ID自己:

<?php 
session_id($someUniqueHash); 
?> 

而且这个作品,如果我做喜欢的MD5(“测试”)的哈希值。在同一台服务器上的其他域上,我们再次进行会话。

问题是生成ID。我在互联网上看到了microtime等的一些解决方案,但是当我使用这种方法时,我无法预测其他域/ PHP页面上的会话ID。

有没有人有想法?或者我们不应该执行这个?是否有其他选项可以在多个域上共享会话? (不是子域!)

+1

为什么不让PHP为您生成会话ID?您可以在各个域之间共享会话ID。这可能是cookie *或*传递查询参数的问题。 – hakre

+0

查询参数不是首选,它是不安全的,不友好的网址。据我所知,你只允许cookies在同一个域名(子域名),而不是多域名。 –

+0

这只是你传递的一个cookie。而且您可以为第三方域创建Cookie,即所谓的第三方Cookie。您可能还需要检查执行此操作的法律方面(旁边解决了技术方面)。顺便说一句,您可能想了解的所有技术细节:[HTTP状态管理机制RFC6265](http://tools.ietf.org/html/rfc6265) – hakre

回答

4

我通过使用OAuth式流量达到了这个系统,但我们替换为用户的消费。

因此,每个域在其自己的会话中都具有经过验证的Access_Token。 然后,您将使用该Access_Token从api获取有关用户的信息。

我还使用session_set_save_handler解决了会话问题,并将会话存储在数据库表中...此表还具有Access_Token,这使得使用DB Query查找会话变得非常简单。

希望这有助于创意。

+0

我一直在考虑最近这样做。我想知道是否有关于存储和检索性能的任何案例研究或简单讨论,方法是将访问令牌添加到数据库表中并查询每个请求。 –

0

嗯,这是一个困难的。

众所周知,当用户回到您的网站时,PHP使用cookie来了解session_ids,并且没有跨域cookie的方式:Cross domain cookies(编辑:有,但方法很复杂)。

这可能是为什么我从来没有见过一个网站实现这一点,即使他们有不同的域名。

通过$ _GET或$ _POST,您可以通过一个域的页面上的链接将会话ID传递给下一个域。如果用户直接进入您的其他网站,这将不起作用。

我能想出的唯一部分(不可靠)方法是记录数据库中的用户计算器,并使用它来了解将会话附加到哪个会话。所以你把电脑的IP地址和其他一些细节放在一个会话中。

个人计算机的IP和其他详细信息会将他们记录到其他域中。

+0

Tnx。有一个网站是这样做的:例如http://www.laptopshop.nl。我知道他们的网站是用PHP开发的,所以这是可能的。但我害怕很难。 –

+0

我确实更正了我的答案,跨域cookie是可能的,但是在那篇文章中,我认为是稳固的,但是跨域域会话真的不可靠... – Sammaye

0

也许这不适合你,但你可以试试这个。

在你的主站你生成会话ID按正常,延续会话到另一个域名,你可以包括在URL中的会话ID图像标记。作为响应,另一个域将设置一个cookie,以便当访问者到达时它已经知道会话ID。

感觉有点聪明的裤子解决方案,但它应该工作,如果你没有太多的其他域:)第三方cookie可以在浏览器中单独禁用btw,需要考虑的事情。

哦顺便说一下,会话通过(通过查询参数接受一个I​​D并设置一个cookie)是一件非常微妙的事情,应该受到保护,即在设置cookie之前会话必须已经存在。

0

配置每个网站单独:

<?php 

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

?> 

为了使多个站点共享会话,让他们用相同的$cfgsession['file']。 包含一个会话从一个网站的请求到另一个网站(也许由Jack推荐),只要你不赶上他们在另一个浏览器或其他任何请求(请做禁止会话劫持) ,让他们用$ _GET指定一个会话。例如:

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); 

然后您只需将自己的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']; 
} 

?>