繁体   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