簡體   English   中英

每個用戶的 PHP 多個並發會話

[英]PHP Multiple Concurrent Sessions Per User

我正在開發一個在 Apache 上使用 PHP 的網絡應用程序。 $_SESSION 變量用於必須跨頁面持久化的信息。

我們需要每個用戶能夠打開多個並發會話,作為新選項卡或新窗口,這取決於他們選擇的瀏覽器。 現在,當用戶打開附加選項卡或窗口並轉到站點時,將采用現有會話。 如何防止這種情況發生,以便用戶必須(或可能)登錄並開始新會話,而不會干擾他們已經打開的任何現有會話?

我們的臨時解決方法是使用多個瀏覽器(IE 和 FF),但這顯然不是一種非常理想的做事方式。

您描述的行為與瀏覽器會話的概念相反。 為什么用戶需要多個會話? 是否需要強制執行用戶訪問控制? 如果是這樣,請將用戶分配到邏輯組並向特定組授予權限。 用戶是否需要代表其他用戶執行某些操作? 如果是這樣,請圍繞該概念設計網站,而不是嘗試為單個用戶創建多個會話。

如果你真的必須這樣做,你可以做一些可怕的事情,比如在頁面之間傳遞一個查詢參數(非常不安全! )作為會話 ID,完全繞過實際的 $_SESSION 並管理你自己的會話概念。 同樣,這不正常,將來只會導致頭痛/安全問題。

可以使用以下偽代碼邏輯模擬非原子並發會話管理訪問:

function main(){
  $locker = new SessionLocking();
  /** read elements the $_SESSION "cached" copy. **/
  $var1 = $_SESSION['var1'];
  $var2 = $_SESSION['var2'];
  /** Pseudo Atomic Read **/
  $locker->lock(); //session is locked against concurrent access.
  $var3 = $_SESSION['var3'];
  $locker->unlock(); //session is committed to disk (or other) and can be accessed by another script.
  /** Psuedo Atomic Write **/
  $locker->lock(); //session is locked against concurrent access.
  $_SESSION['var4'] = "Some new value";
  $locker->unlock(); //session is committed to disk (or other) and can be accessed by another script
}

CLASS SessionLocking {

private static $lockCounter=0;
private static $isLoaded=false;

function __constructor(){
  if (!self::$isLoaded) load();
}

private function load(){
 $this->lock();
 $this->unlock();
}

private function lock(){
  if ($lockCounter<1) try {session_start();} Catch(){}
  $lockCounter++; 
}

private function unlock(){
  if ($lockCount<1) return;
  $lockCounter--;
  if ($lockCounter<1) try {session_write_close();} Catch(){}
}
}

如果可能的話,這將是非常困難的。

會話不必擔心它們在哪個選項卡中。

另外,如果選項卡 1 中的會話 1 打開一個新窗口會發生什么? 是新的會話嗎?

知道這是一個很晚的答案......

作為開發者,我通常需要同時測試不同用戶類型(管理員、注冊、訪問者等)的界面。 Firefox 瀏覽器有一個“Multi-Account Containers”附加組件,除其他外,它使 cookie 按容器分開。 可以根據需要創建盡可能多的容器,並在每個容器內打開選項卡。 每組包含的選項卡共享 cookie,但不跨容器共享。 瀏覽器將使用不同的獨立“PHPSESSID”(或您如何命名 cookie),從而能夠處理多個同時會話。

還有其他擴展和注意事項,例如特殊書簽等,但它們超出了此處的問題范圍。

這是一種方法:

-首先在 php.ini 中禁用會話 cookie:

session.use_cookies = 0

這可確保不使用 cookie 來傳遞會話 ID。

-then 確保生成包含會話 id 的所有 URL(您通過函數 session_id() 獲得它,例如:

print "<a href= \"http://www.example.com/".session_id()."&showlist=1\">show list</a>";

暫無
暫無

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

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