Sni*_*ire 5 php session laravel
我在 2 个不同的域 domain1.tld 和 domain2.tld 中创建了 2 个项目。
domain1.tld 是主要的事件生产者页面,而 domain2.tld 是其事件之一。我想共享相同的会话(它们实际上共享相同的数据库和相同的 apache 服务器)。我试图将会话驱动程序更改为“数据库”并创建一个会话表,但没有任何反应,如果我登录 domain1.tld,则在 domain2.tld 中没有任何反应。
我真的在网上搜索过,但我什么也没找到
你不能以你的方式做到这一点......
当您设置会话时,在浏览器中设置的 cookie 用于跟踪服务器端存储的会话。
如果您想在两个域之间共享会话,您应该在站点机器人之间共享 cookie,您不能这样做(您只能在一个域的子域中进行)
但有一个小技巧:最简单的解决方法是将登录/凭据信息从网站 A 传递到网站 B,并让网站 B 设置单独的 cookie。例如,在登录网站 A 后,您可以使用加密的查询字符串将它们快速重定向到网站 B。然后网站 B 可以读取信息,设置自己的 cookie,并将用户重定向回网站 A。
这很乱,但有可能。
第 1 步:为共享会话数据设置会话驱动程序
首先,将会话驱动程序设置为跨两个域共享的数据库或缓存。您的会话驱动程序不能是文件
步骤 2:实施跨域会话 ID
会话 ID 在 Laravel 中通过 cookie 传递。由于您的网站位于不同的域中,因此会话 cookie 不会传输。解决此问题的一种方法是将它们附加到所有请求的查询字符串中,如下所示:domain2.tld/?session_token=abcds2342
在您的代码中,必须有某种登录来检测会话,然后查询数据库/缓存(您的会话驱动程序)以获取结果。如果找到结果,则手动设置会话 ID 并启动会话:
session_id('abcds2342');
session_start();
Run Code Online (Sandbox Code Playgroud)
请仔细检查 IP 地址和会话 ID,以防止人们猜测别人的 SessionID 从而以其他人的身份登录
步骤 2A:为此,您可以实现一个覆盖 StartSession 的自定义中间件。这个中间件应该重写 getSession ,并在检查 cookie 中的 session_id 之前,检查请求中是否存在令牌。示例代码如下:
<?php
namespace App\Http\Middleware;
use Illuminate\Session\Middleware\StartSession;
use Illuminate\Http\Request;
use App\SessionShare;
use Closure;
class StartSessionWithSharer extends StartSession
{
/**
* Get the session implementation from the manager.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Session\SessionInterface
*/
public function getSession(Request $request)
{
$session = $this->manager->driver();
/**
* Check if we can find a valid session token from saved records
*/
if($request->get('session_token') && !empty($request->get('session_token'))) {
$sessionShare = SessionShare::valid()->whereToken($request->get('session_token'))->first();
if($sessionShare)
$session_id = $sessionShare->session_id;
}
/**
* Fallback to session in browser
*/
if(!isset($session_id) || !$session_id)
$session_id = $request->cookies->get($session->getName());
$session->setId($session_id);
return $session;
}
}
Run Code Online (Sandbox Code Playgroud)
步骤 2B:然后创建一个自定义服务提供者来覆盖 SessionServiceProvider,如下所示:
<?php namespace App\Providers;
class CustomSessionServiceProvider extends \Illuminate\Session\SessionServiceProvider
{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->registerSessionManager();
$this->registerSessionDriver();
$this->app->singleton('App\Http\Middleware\StartSessionWithSharer');
}
}
Run Code Online (Sandbox Code Playgroud)
然后从 config/app.php 中删除旧的 SessionServiceProvider 并改为使用上面的内容。
步骤 2C:然后为表创建 App\SessionShare 模型来存储会话 ID。另外,上面的代码不负责检查 IP 地址,因此您必须添加它以确保其安全并防止暴力攻击
步骤 2D:哦,最后不要忘记为所有请求附加 session_token 的 get 参数
请注意,上述实现是针对数据库会话驱动程序的。当然,您也可以对缓存驱动程序执行此操作。唯一会改变的是验证会话的模型实现(步骤 2C)