簡體   English   中英

如何在php中生成唯一的會話ID

[英]How to generate a unique session ID in php

在我們的網站上,我們希望能夠在多個域中共享會話。 所有這些網站都在同一台服務器上,但其中一些網站有不同的IP地址。

我找到的可能解決方案是自己設置會話ID:

<?php
session_id($someUniqueHash);
?>

如果我像md5('test')那樣制作哈希,這就有效。 在同一服務器上的另一個域上,我們再次進行會話。

問題是生成ID。 我在互聯網上看到一些使用microtime等的解決方案,但是當我使用這種方法時,我無法預測其他域/ PHP頁面上的會話ID。

有沒有人有想法? 或者我們不應該實現這個? 是否有其他選項可以在多個域上共享會話? (不是子域名!)

我通過使用OAuth類型流程實現了這個系統,但我們用User替換了Consumer。

因此,每個域將在其自己的會話中具有經過身份驗證的Access_Token。 然后,您將使用該Access_Token從api獲取有關用戶的信息。

我還使用session_set_save_handler解決了會話問題並將會話存儲在數據庫表中......此表也具有Access_Token,這使得使用DB Query查找會話非常容易。

希望這有助於提出想法。

嗯,這是一個困難的問題。

眾所周知,當用戶回到您的站點並且無法跨域cookie時,PHP使用cookie來理解session_id: 跨域cookie (編輯:有但方法很復雜)。

這可能就是為什么我從未見過網站實現這一點,即使它們有不同的域。

您可以通過頁面上的鏈接從一個域通過$ _GET或$ _POST將會話ID傳遞給下一個域。 如果用戶直接進入您的其他網站,則無法使用此功能。

我能想到的唯一部分(不可靠)方法是在DB中保留用戶計算器的記錄,並使用它來了解附加到哪個會話。 因此,您可以存放計算機的IP地址,也可能包含一些其他詳細信息,並將其備份到會話中。

人員計算機的IP和其他詳細信息會將其記錄到另一個域中。

也許這不是你的選擇,但你可以試試這個。

在您的主站點上,您可以按照正常情況生成會話ID,並將會話永久保存到另一個域,您可以在URL中包含具有會話ID的圖像標記。 作為回應,另一個域將設置一個cookie,以便當訪問者到達那里時它已經知道會話ID。

感覺有點聰明的褲子解決方案,但它應該工作,如果你沒有太多的其他域:)第三方cookie可以在瀏覽器中單獨禁用btw,需要考慮的事情。

哦順便說一句,會話采用(通過查詢參數接受id並設置cookie)是很微妙的東西,應該受到保護,即在設置cookie之前會話必須已經存在。

單獨配置每個站點:

<?php

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

?>

要讓多個站點共享會話,請讓他們使用相同的$cfgsession['file'] to inhibit session hijacking), let them specify a session with $_GET. 在請求中將一個會話從一個站點包含到另一個域(可能是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'];
}

?>

如果這些是登錄會話,請考慮使用單點登錄(SSO)解決方案,例如實施SAML標准的解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM