Laravel,2个域中的2个项目在同一会话中 [英] Laravel, 2 projects in 2 domains same session

查看:401
本文介绍了Laravel,2个域中的2个项目在同一会话中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm creating 2 projects in 2 diferent domains domain1.tld and domain2.tld.

domain1.tld是主事件生成器页面,domain2.tld是其事件之一.我想共享相同的会话(它们实际上共享相同的数据库和相同的apache服务器).我试图将会话驱动程序更改为数据库"并创建一个会话表,但是什么也没有发生,如果我登录到domain1.tld,则在domain2.tld中什么也没有发生.

The domain1.tld is the main event producer page and the domain2.tld is one of its events. I want to share the same sessions (they actually share the same database and the same apache server). I tried to change the session driver to "database" and create a session table, but nothing happens, if i'm log in domain1.tld nothing happens in domain2.tld.

我确实在网上搜索过,但是什么也没找到

I really have searched in the net but i have found nothing

推荐答案

步骤1:为共享会话数据设置会话驱动程序

首先,将会话驱动程序设置为在两个域之间共享的数据库或缓存.您的会话驱动程序不能为文件

First, set your session driver to a database or cache that is shared across both domains. Your session driver cannot be file

第2步:实施跨域会话ID

会话ID由Laravel中的cookie传递.由于您的网站位于不同的域中,因此会话Cookie不会转移.解决此问题的一种方法是将它们附加到所有请求的查询字符串中,如下所示:domain2.tld/?session_token = abcds2342

Session ids are passed around by cookies in Laravel. Since your websites are on different domains the session cookie does not transfer over. One way to solve this is to append them to the query string of all your requests like so: domain2.tld/?session_token=abcds2342

在您的代码中,必须有一些登录名可以检测到会话,然后查询数据库/缓存(您的会话驱动程序)以获取结果.如果找到结果,则手动设置会话ID并启动会话:

Within your code there must be some login that detects a session and then query the database/cache (your session driver) for a result. If a result is found, you set the session ID manually and start the session:

session_id('abcds2342');
session_start();

请务必同时检查IP地址和会话ID 防止人们猜测别人的SessionID,从而 以其他人身份登录

Be careful to check both the IP address and the session ID to prevent people from guessing someone elses SessionID and thus logging in as another person

第2A步:要执行此操作,您可以实施覆盖StartSession的自定义中间件.该中间件应覆盖getSession,并在检查cookie中的session_id之前,请检查请求中是否存在令牌.下面的示例代码:

Step 2A: To do this you can implement a custom middleware that overrides StartSession. This middleware should override getSession and before it checks for session_id in cookie, check if we have a token present in the Request. Sample code below:

<?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;
    }
}

步骤2B :然后创建一个自定义服务提供商,以覆盖SessionServiceProvider ,如下所示:

Step 2B: Then create a custom service provider to override SessionServiceProvider like so:

<?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');
    }
}

,然后从config/app.php中删除旧的SessionServiceProvider,并在上面使用.

And then remove the old SessionServiceProvider from config/app.php and instead use above.

步骤2C:,然后为表创建App \ SessionShare模型,以存储会话ID.另外,上面的代码不会检查IP地址,因此您必须添加它以确保其安全并防止暴力攻击

Step 2C: Then create your App\SessionShare model for the table to store session IDs. Also, the above code doesn't take care of checking IP address so you would have to add that in to make it secure and prevent brute force attacks

步骤2D:哦,最后不要忘了为所有请求附加session_token的get参数

请注意,以上实现是针对数据库会话驱动程序的.当然,您也可以为缓存驱动程序执行此操作.唯一会改变的是用于验证会话的模型实现(步骤2C)

Note that the above implementation is for a database session driver. Of course, you can do this for a cache driver too. The only thing that would change is the model implementation (step 2C) to validate the session

这篇关于Laravel,2个域中的2个项目在同一会话中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆