PHP 每个用户的多个并发会话

我正在Apache上使用PHP开发一个Web应用程序。$_SESSION变量被大量用于必须跨页面保留的信息。

我们需要每个用户能够打开多个并发会话,无论是作为新选项卡还是新窗口,具体取决于他们选择的浏览器。现在,当用户打开添加选项卡或窗口并转到站点时,将采用现有会话。如何防止这种情况,以便用户必须(或可能)登录并启动新会话,而不会干扰他们已经打开的任何现有会话?

我们的临时解决方法是使用多个浏览器(IE和FF),但这显然不是一种非常理想的做事方式。


答案 1

您描述的行为与浏览器会话的概念相反。为什么用户需要多个会话?是否需要强制执行用户访问控制?如果是这样,请将用户分配到逻辑组并向特定组授予权限。用户是否需要代表其他用户执行某些操作?如果是这样,请围绕该概念设计网站,而不是尝试为单个用户创建多个会话。

如果你真的必须这样做,你可以做一些可怕的事情,比如在页面之间传递一个查询参数(非常不安全!)作为会话ID,完全绕过实际的_SESSION美元,并管理你自己的会话概念。同样,这是不正常的,只会在未来导致头痛/安全问题。


答案 2

可以使用以下伪编码逻辑模拟非原子并发会话管理访问:

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(){}
}
}

推荐