[英]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.