来自同一浏览器的 Laravel 和多会话
在我们的 Web 应用程序中,如果我使用单个浏览器,请以用户 A 的身份登录我们的应用程序,打开另一个选项卡并以用户 B 的身份登录 - 用户 A 会丢失他的会话数据.我认为这是由于用户代理创建的共享 cookie.有没有办法用用户名连接它的名字?以便会话可以在同一台机器上使用相同浏览器的并发登录用户之间共存?
In our web app, If I use a single browser, login to our application as user A, open another tab and login as user B - User A loses his session data. I assume this is due to a shared cookie made out with the user-agent. Is there a way to concat its name with a username? so that sessions can co-exist between concurrent logged in users using the same browser on the same machine?
我们使用 Laravel 5.有什么解决办法吗?
We use Laravel 5. Is there any way around it?
推荐答案
Laravel Session 背景
会话
跳过此部分以获得快速简单的解决方案
在 Laravel 中,会话 cookie 是通过 IlluminateSessionSessionManager
类创建的,即通过 buildSession
方法:
In Laravel, session cookies are created via the IlluminateSessionSessionManager
class, namely through the buildSession
method:
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);
}
}
在这个方法中,我们可以清楚地看到会话的名称来自我们的configsession.php
,特别是这一行:
In this method we can clearly see that the name of the session comes from our configsession.php
, looking in particular this line:
session.php
'cookie' => 'laravel_session', # ~~ ln 121 at time of writing
好的,但这并没有多大帮助,改变它,改变它无处不在,正如在配置中进行的评论所指出的那样.
Ok, but that doesn't help a lot, changing this, changes it everywhere, as noted by the comment proceeding it in the config.
此处指定的名称将在每次新会话 cookie 时使用由框架为每个驱动程序创建.
The name specified here will get used every time a new session cookie is created by the framework for every driver.
即使我们可以传递一些动态值,例如:
And even if we could pass it some dynamic value, something like:
'cookie' => 'laravel_session' . user()->id,
这会产生一个矛盾的、时间结束的、宇宙内爆的结果,因为您从通过 session
访问的 user
请求 id
通过 cookie
名称 laravel_session
查找..(脑残)
This creates a paradoxical, time ending, universe imploding outcome because you are requesting the id
from the user
which is accessed via the session
looked up by the cookie
name laravel_session
.. (mindblown)
让我们离开 SessionManager
而它是 session.php
配置.我们可以从上面看到,无论我们如何处理,我们所有的会话信息都将归入该单个 laravel_session
键下.
Let's leave SessionManager
and it's session.php
configuration alone. We can see from above that regardless of how we approach this, all our session info will be fall under that single laravel_session
key.
也许 Guard 会有更多信息.
Maybe Guard will have some more information.
Guard 是您对应用程序进行身份验证的关键,也是使 Laravel 能够快速创建应用程序的众多因素之一.
Guard is your key to auth into your app, and one of the many things that makes Laravel awesome for quickly creating applications.
要查看的方法是Guard::user()
.
Guard::user()
在一些初始缓存和注销检查之后做的第一件事就是会话检查.
One of the first things Guard::user()
does after some initial cache and logged out checking, is a session check.
Guard::user()
$id = $this->session->get($this->getName());
所以在这里,Laravel 正在获取与 getName()
的结果匹配的会话值 - 太棒了 - 我们需要做的就是 mod getName()
返回一个值,让我们来看看那个方法:
So here, Laravel is fetching the session values that match the result of getName()
- awesome - all we need to do is mod getName()
to return a value, let's take a took at that method:
Guard::getName()
public function getName()
{
return 'login_'.md5(get_class($this));
}
这很直接.$this
指的是 Guard 类,因此 md5 将有效地始终相同(如果有人知道 md5 背后的为什么"每次都相同的类名,请发表评论).
That's pretty straight forward. $this
refers to the Guard class, so the md5 will effectively always be the same (if anyone knows the 'why' behind md5'ing the class name which would be the same each time, leave a comment).
有几个地方应该更新这个,比如getRecallerName
.
There are a few places where this should be updated, such as getRecallerName
.
因此,从这里开始,您可以扩展核心 Guard
类并拼接您的 getName 和 getRecallerName 方法.
So from here, you can extend the core Guard
class and splice in your getName and getRecallerName methods.
您可能希望围绕此包装一些服务提供者,编写一些单元测试,甚至可能覆盖原始身份验证管理器.
You will probably want to wrap some service provider around this, write some unit tests, possibly even overwrite the original auth manager.
天哪,这看起来工作量很大"
"Geez, that seems like a lot of work"
肯定是比利,肯定是"
https://www.youtube.com/watch?v=dTxQ9yhGnAg
看下一部分
Ollie Read 已经创建了一个解决方案,可在此处找到:
Ollie Read has already created a solution, found here:
https://github.com/ollieread/multiauth
我鼓励您查看一下,尤其是自定义 Guard
类,它使用自定义 getName
方法扩展了核心 Guard
.
I encourage you to have a look, especially the custom Guard
class which extends core Guard
with custom getName
methods.
相关文章