来自同一浏览器的laravel和多会话

时间:2015-10-23 21:38:35

标签: php laravel laravel-5

在我们的网络应用程序中,如果我使用单个浏览器,请以用户A身份登录我们的应用程序,打开另一个选项卡并以用户B身份登录 - 用户A丢失其会话数据。我假设这是由于与用户代理共享的cookie。有没有办法用用户名连接其名称?这样会话可以在同一台机器上使用相同浏览器的并发登录用户之间共存?

我们使用Laravel 5.有什么方法吗?

8 个答案:

答案 0 :(得分:22)

Laravel会话背景

会话

跳过此部分以获得快速简便的解决方案

在Laravel中,会话cookie是通过Illuminate\Session\SessionManager类创建的,即通​​过buildSession方法:

<强> SessionManager :: buildSession

protected function buildSession($handler)
{
    if ($this->app['config']['session.encrypt']) {
        return new EncryptedStore(
            $this->app['config']['session.cookie'], $handler, $this->app['encrypter']
        );
    } else {
        return new Store($this->app['config']['session.cookie'], $handler);
    }
}

在这种方法中,我们可以清楚地看到会话的名称来自我们的config\session.php,特别关注这一行:

<强> session.php文件

'cookie' => 'laravel_session', # ~~ ln 121 at time of writing

好的,但这并没有多大帮助,改变它,随处更改,正如配置中的评论所述。

  

每次新会话cookie时都会使用此处指定的名称   是由每个驱动程序的框架创建的。

即使我们可以传递一些动态值,例如:

'cookie' => 'laravel_session' . user()->id,

这会产生一个矛盾的,时间结束的,宇宙爆炸的结果,因为您要求id user sessioncookie通过laravel_session查询SessionManager姓名session.php ..(精神萎靡)

让我们单独留下laravel_sessionGuard::user()个配置。我们可以从上面看到,无论我们如何处理此问题,我们所有的会话信息都将归入单Guard::user()项。

保护

也许Guard会有更多信息。

Guard是您进入应用程序的关键,也是使Laravel快速创建应用程序的众多因素之一。

要查看的方法是$id = $this->session->get($this->getName());

getName()在初始缓存和注销检查后所做的第一件事就是会话检查。

<强>员::用户()

getName()

所以在这里,Laravel正在获取与public function getName() { return 'login_'.md5(get_class($this)); } 的结果匹配的会话值 - 非常棒 - 我们需要做的就是mod $this来返回一个值,让我们采取一种方法:

<强>员::的getName()

getRecallerName

这很直截了当。 Guard指的是Guard类,所以md5实际上总是相同的(如果有人知道md5背后的'为什么',每次都是相同的类名,留下评论)。

有一些地方应该更新,例如Guard

因此,从这里开始,您可以扩展核心Guard类并拼接您的getName和getRecallerName方法。

您可能希望围绕此包装一些服务提供者,编写一些单元测试,甚至可能覆盖原始的auth管理器。

  

“Geez,这似乎很多工作”

     

“肯定是比利,肯定是”

     

https://www.youtube.com/watch?v=dTxQ9yhGnAg

见下一部分

快速“我只需要一个答案”答案

Ollie Read已经创建了一个解决方案,可在此处找到:

https://github.com/ollieread/multiauth

我们建议您查看一下,尤其是使用自定义getName方法扩展核心import xml.dom.minidom DOMTree = xml.dom.minidom.parse("C:/Users/Desktop/PythonXMLproject/Smallfile.xml") collection = DOMTree.documentElement instrumentDatas = collection.getElementsByTagName("instrumentData") for instrumentData in instrumentDatas: idx = instrumentData.getElementsByTagName("id")[0].firstChild.data print "ID: %s" % idx datas = instrumentData.getElementsByTagName("data") for data in datas: if data.hasAttribute('value'): value = data.getAttribute('value') print "Value: %s" % value 的自定义$str = str_replace(". ", ".\n", $str); 类。

答案 1 :(得分:1)

任何主要浏览器都只会为网站存储一个会话Cookie,但网站开发者可以选择该Cookie中的内容。您的网站似乎将用户信息存储在会话cookie中,当其他选项卡在同一个cookie中存储不同的信息时,会被覆盖。

您没有提供有关特定网站如何运作的详细信息,但以下是解决此问题的一些常用方法。

1)为不同的用户使用不同的浏览器。不同的浏览器不会在它们之间共享Cookie。如果您的目标只是测试多个用户的网站,那就是这样。您还可以使用隐身/私密模式登录单独的用户,因为此模式也不会共享Cookie。

2)不要使用会话cookie来存储用户信息。这在大多数网站上都不是首发,但如果这是一个内部网站或严格控制的环境,你可能会能够通过URL,POST数据或请求中的其他隐藏标识符传递用户标识。

3)将数据存储在所有当前登录用户的会话Cookie中。根据网络框架,可以创建user - &gt;的地图。 cookieData根据发出请求的用户查找正确的。{1}}。这是一项先进的技术,我实际上并不知道Laravel是否暴露了这种控制水平。

答案 2 :(得分:1)

tl; dr:Yagni

考虑一个人(您的案例中为http客户端),其中包含两个身份:Dr JekyllMr Hyde
他拜访了他的新朋友Sir RM1970(在你的情况下是http服务器):&#34; 你好,RM1970&#34;。
这是问题所在。差RM1970需要欢迎怪物,并且几乎没有选择:

  • 深入到这个兔子洞里:&#34; 你如何同时做Dr JekyllMr Hyde&#34;,这使得进一步的对话难以置信(你的例如,ACl需要使用身份列表进行操作,并在实时冲突时做出优先级决定。)
  • 自己做出决定:&#34; 你如何做Dr Jekyll&#34;并祈祷你做出了正确的选择(随机选择用户的身份,并通过不可预知的回应为您的用户带来一些乐趣)
  • 狡猾,把这个责任转回给他:&#34; 请原谅我?你是谁?为自己命名!&#34; (每个请求需要单个身份)

后者是它的实际工作方式。浏览器提供最新的确认身份 你被要求改变这个,但你真的想要吗?坚持不懈,不承担这一责任 如果您没有使用前2个死胡同选项,则需要询问用户代表他发送请求的位置。这里最好的选择是使您的前端有状态,维护已打开会话的列表,并提供用户选择一个UI。它几乎是第三个Ryan Bemrose的选项,但是将这些数据存储在客户端,并仅发送所选择的数据。 laravel后端不需要改变。

这里的问题是切换选项卡不会自动切换用户,并且会相当混乱,与已经实现的注销/登录路径差别很小。

某些浏览器支持多个配置文件(example),这可能是一种可接受的选择。基本上它与第一个Ryan Bemrose的选项相同,但不需要安装多个浏览器,并且可以从永久性cookie中受益,也就是“记住我”。

答案 3 :(得分:1)

最简单的只是一个基于URL的sessionID,这可能是一个安全问题,具体取决于您的应用程序的设计方式,尤其是在与非过期会话共享网址时。

由于L5不再支持php本机会话,因此您必须使用如下的自定义提供程序:

这将在laravel V5的网址中使用sessionID:

https://github.com/iMi-digital/laravel-transsid

基本上,会话是基于URL的,因此您只需登录其他选项卡并获取新的会话ID,该人员就可以轻松地在新标签页中打开&#34;打开页面&#34;如果需要,也有两个相同用户的页面。

上面的库将会话锁定到IP和用户代理,因此链接共享不会意外泄漏会话。

答案 4 :(得分:0)

我并不完全知道你需要什么,但作为开发人员,我有时必须登录到有多个用户的应用程序。要做到这一点,我通常使用隐身模式,或者如果超过2个用户,我在Chrome中使用this扩展名有一些运气。

我知道这不是你问题的答案,但它可能就是你想要的。

答案 5 :(得分:0)

并发登录用户之间共存的不同视图不能仅仅由会话cookie实现,因为cookie是由浏览器存储的。所以登录了 在用户的视线中必须由服务器存储。 众所周知,一旦调用session_start,就会创建SessionID,然后在服务器的临时文件中创建临时文件 。目录

不同的用户具有不同的SessionID,并且在调用session_destory之后,将恢复存储在服务器和Cookie中的所有SessionID。您可以通过实现SessionHandlerInterface来重写此行为。由于许多Web框架支持这一点,Laravel也不例外。 这是文件: custom-session-drivers

答案 6 :(得分:0)

我不知道将它编码到laravel是多么复杂但这可能是一个解决方案:

您使用不同的会话名称,必须是字符串,并且每次都将其编码到URL中,以便应用程序知道哪个用户发出了请求。因此,您可以使用普通名称调用会话变量。

<?php
if(isset($_GET['id']) && !empty($_GET['id']))
    session_name($_GET['id']);
session_start();

if(isset($_GET['user'])) {
    $_SESSION['user'] = $_GET['user'];
}

if(!empty($_SESSION['user']))
    echo "Hello ".$_SESSION['user'];

答案 7 :(得分:0)

具有相同浏览器的多用户登录,例如Google添加帐户。为此你需要按照一些步骤重新编写Laravel提供的auth库,

步骤

  

备份您的Auth文件。

     

更改所有会话存储功能,将其先存储在数组中,然后将该数组存储到会话

     

现在你需要创建一个新的会话变量,它将存储当前用户实例id,如user 0 1 2 ...

     

现在您需要更改所有功能,您将从会话中获取您需要检查的会话对象是否为空,然后用户注销,否则您需要在用户实例上获取用户群的数据。 / p>      

当用户想要从一个帐户切换到另一个帐户时,您需要更改实例。