問(wèn)題描述
在我們的 Web 應(yīng)用程序中,如果我使用單個(gè)瀏覽器,請(qǐng)以用戶 A 的身份登錄我們的應(yīng)用程序,打開(kāi)另一個(gè)選項(xiàng)卡并以用戶 B 的身份登錄 - 用戶 A 會(huì)丟失他的會(huì)話數(shù)據(jù).我認(rèn)為這是由于用戶代理創(chuàng)建的共享 cookie.有沒(méi)有辦法用用戶名連接它的名字?以便會(huì)話可以在同一臺(tái)機(jī)器上使用相同瀏覽器的并發(fā)登錄用戶之間共存?
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 背景
會(huì)話
跳過(guò)此部分以獲得快速簡(jiǎn)單的解決方案
在 Laravel 中,會(huì)話 cookie 是通過(guò) IlluminateSessionSessionManager
類創(chuàng)建的,即通??過(guò) 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);
}
}
在這個(gè)方法中,我們可以清楚地看到會(huì)話的名稱來(lái)自我們的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
好的,但這并沒(méi)有多大幫助,改變它,改變它無(wú)處不在,正如在配置中進(jìn)行的評(píng)論所指出的那樣.
Ok, but that doesn't help a lot, changing this, changes it everywhere, as noted by the comment proceeding it in the config.
此處指定的名稱將在每次新會(huì)話 cookie 時(shí)使用由框架為每個(gè)驅(qū)動(dòng)程序創(chuàng)建.
The name specified here will get used every time a new session cookie is created by the framework for every driver.
即使我們可以傳遞一些動(dòng)態(tài)值,例如:
And even if we could pass it some dynamic value, something like:
'cookie' => 'laravel_session' . user()->id,
這會(huì)產(chǎn)生一個(gè)矛盾的、時(shí)間結(jié)束的、宇宙內(nèi)爆的結(jié)果,因?yàn)槟鷱耐ㄟ^(guò) session
訪問(wèn)的 user
請(qǐng)求 id
通過(guò) 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)
讓我們離開(kāi) SessionManager
而它是 session.php
配置.我們可以從上面看到,無(wú)論我們?nèi)绾翁幚恚覀兯械臅?huì)話信息都將歸入該單個(gè) 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 會(huì)有更多信息.
Maybe Guard will have some more information.
Guard 是您對(duì)應(yīng)用程序進(jìn)行身份驗(yàn)證的關(guān)鍵,也是使 Laravel 能夠快速創(chuàng)建應(yīng)用程序的眾多因素之一.
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()
在一些初始緩存和注銷檢查之后做的第一件事就是會(huì)話檢查.
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()
的結(jié)果匹配的會(huì)話值 - 太棒了 - 我們需要做的就是 mod getName()
返回一個(gè)值,讓我們來(lái)看看那個(gè)方法:
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 背后的為什么"每次都相同的類名,請(qǐng)發(fā)表評(píng)論).
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).
有幾個(gè)地方應(yīng)該更新這個(gè),比如getRecallerName
.
There are a few places where this should be updated, such as getRecallerName
.
因此,從這里開(kāi)始,您可以擴(kuò)展核心 Guard
類并拼接您的 getName 和 getRecallerName 方法.
So from here, you can extend the core Guard
class and splice in your getName and getRecallerName methods.
您可能希望圍繞此包裝一些服務(wù)提供者,編寫(xiě)一些單元測(cè)試,甚至可能覆蓋原始身份驗(yàn)證管理器.
You will probably want to wrap some service provider around this, write some unit tests, possibly even overwrite the original auth manager.
天哪,這看起來(lái)工作量很大"
"Geez, that seems like a lot of work"
肯定是比利,肯定是"
https://www.youtube.com/watch?v=dTxQ9yhGnAg
看下一部分
Ollie Read 已經(jīng)創(chuàng)建了一個(gè)解決方案,可在此處找到:
Ollie Read has already created a solution, found here:
https://github.com/ollieread/multiauth
我鼓勵(lì)您查看一下,尤其是自定義 Guard
類,它使用自定義 getName
方法擴(kuò)展了核心 Guard
.
I encourage you to have a look, especially the custom Guard
class which extends core Guard
with custom getName
methods.
這篇關(guān)于來(lái)自同一瀏覽器的 Laravel 和多會(huì)話的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!