Laravel,同一会话中 2 个域中的 2 个项目

Sni*_*ire 5 php session laravel

我在 2 个不同的域 domain1.tld 和 domain2.tld 中创建了 2 个项目。

domain1.tld 是主要的事件生产者页面,而 domain2.tld 是其事件之一。我想共享相同的会话(它们实际上共享相同的数据库和相同的 apache 服务器)。我试图将会话驱动程序更改为“数据库”并创建一个会话表,但没有任何反应,如果我登录 domain1.tld,则在 domain2.tld 中没有任何反应。

我真的在网上搜索过,但我什么也没找到

Mah*_*bar 5

你不能以你的方式做到这一点......

当您设置会话时,在浏览器中设置的 cookie 用于跟踪服务器端存储的会话。

如果您想在两个域之间共享会话,您应该在站点机器人之间共享 cookie,您不能这样做(您只能在一个域的子域中进行)

但有一个小技巧:最简单的解决方法是将登录/凭据信息从网站 A 传递到网站 B,并让网站 B 设置单独的 cookie。例如,在登录网站 A 后,您可以使用加密的查询字符串将它们快速重定向到网站 B。然后网站 B 可以读取信息,设置自己的 cookie,并将用户重定向回网站 A。

这很乱,但有可能。


Par*_*ras 2

第 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)