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

2022-08-30 16:39:55

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

我们使用Laravel 5。有什么办法可以解决这个问题吗?


答案 1

拉拉维尔会议背景

会话

跳过此部分,快速获得简单的解决方案

在Laravel中,会话cookie是通过类创建的,即通过以下方法:Illuminate\Session\SessionManagerbuildSession

会话管理器::构建会话

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

会话.php

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

好吧,但这并没有多大帮助,改变这一点,到处改变它,正如配置中的评论所指出的那样。

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

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

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

这创造了一个矛盾的,时间结束的,宇宙崩溃的结果,因为你正在请求通过名称查找的访问。(头脑清醒)idusersessioncookielaravel_session

让我们离开,它只是配置。从上面可以看出,无论我们如何做到这一点,我们所有的会话信息都将属于该单个键。SessionManagersession.phplaravel_session

警卫

也许Guard会有更多的信息。

Guard是你授权到你的应用程序中的关键,也是使Laravel在快速创建应用程序方面表现出色的众多因素之一。

要查看的方法是 。Guard::user()

在进行一些初始缓存和注销检查后,首先要做的一件事就是会话检查。Guard::user()

后卫::用户()

$id = $this->session->get($this->getName()); 

所以在这里,Laravel正在获取与结果匹配的会话值 - 真棒 - 我们需要做的就是mod返回一个值,让我们采用该方法:getName()getName()

Guard::getName()

public function getName()
{
    return 'login_'.md5(get_class($this));
}

这很简单。 指的是 Guard 类,因此 md5 实际上始终是相同的(如果有人知道 md5 后面的“为什么”,每次都会相同的类名,请留下注释)。$this

有几个地方应该更新它,例如.getRecallerName

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

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

“哎呀,这似乎需要做很多工作”

“肯定是比利,肯定是”

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

请参阅下一部分

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

Ollie Read已经创建了一个解决方案,可以在这里找到:

https://github.com/ollieread/multiauth

我鼓励您看一看,特别是使用自定义方法扩展核心的自定义类。GuardGuardgetName


答案 2

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

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

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

2) 不要使用会话 Cookie 来存储用户信息。这在大多数网站上都是非入门级的,但如果这是内部站点或严格控制的环境,则可以通过URL,POST数据或请求中的其他一些隐藏标识符传递用户标识。

3) 将所有当前登录用户的数据存储在会话 Cookie 中。根据 Web 框架的不同,可以创建 -> 的映射,并根据发出请求的用户查找正确的映射。这是一种先进的技术,我实际上并不知道Laravel是否暴露了这种程度的控制。usercookieData


推荐