首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >域和子域的Laravel共享cookie检测问题

域和子域的Laravel共享cookie检测问题
EN

Stack Overflow用户
提问于 2017-08-18 15:16:47
回答 4查看 4K关注 0票数 21

我在研究Laravel 5.4.30。

假设我们有一个域example.com和一个dev.example.com子域。主域为主分支,开发子域为开发分支。我们有cookie通知系统,它将在单击Hide Cookie Notice按钮后隐藏。这是通过设置一个永久的cookie来实现的。我们已经将SESSION_DOMAIN信任设置为每个环境的每个域。

对于主域:

代码语言:javascript
运行
复制
SESSION_DOMAIN=example.com

对于dev子域:

代码语言:javascript
运行
复制
SESSION_DOMAIN=dev.example.com

现在问题就在这里。如果我们转到example.com并单击隐藏cookie通知,将永久为主域设置cookie。在那之后,我们去dev.example.com并做同样的事情。因此,cookie也将被设置为子域。但是这个曲奇是在前一个之后设置的。(订单是重要的)现在,如果我们刷新子域,我们将再次看到通知!(而不是隐藏的)由于浏览器中cookie的.example.com参数设置了domain,浏览器读取了主cookie,因此每个子域都会受到影响。但是视图仍然显示通知,因为它不能读取任何用于隐藏的cookie。

无论如何,我不想在所有的子域上分享这个曲奇。我怎样才能做到这一点?我想我应该为曲奇名字加上一个前缀。但我不知道该怎么做,那只拉拉自动在曲奇名字上加上前缀。

有什么解决办法吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-08-22 17:22:18

您需要实现自己的“检索”和“设置”cookie。

检索(有,获取)曲奇

创建自己的新类(任何你喜欢的地方,但我会用名称Cookie做app/Foundation/Facades/) )。

代码语言:javascript
运行
复制
use \Illuminate\Support\Facades\Cookie as CookieStock;

class Cookie extends CookieStock { 
    //implement your own has(...);
    public static function has($key)
    {
        return ! is_null(static::$app['request']->cookie(PREFIX . $key, null)); //get the prefix from .env file for your case APP_ENV
    }

    //implement your own get(...);
    public static function get($key = null, $default = null) {...}
}

现在打开config/app.php并更改相应的别名(cookie)。

设置(制作)曲奇

创建自己的新提供者(使用技工),并从Illuminate\Cookie\CookieServiceProvider.php复制粘贴代码并更改名称空间。再次打开config/app.php并使用新的服务提供者更改相应的服务提供者。

创建自己的新类(任何您喜欢的地方,但我会使用名称为app/Foundation/Cookie/)的CookieJar。

代码语言:javascript
运行
复制
use \Illuminate\Cookie\CookieJar as CookieJarStock;

class CookieJar extends CookieJarStock {

//Override any method you think is relevant (my guess is make(), I am not sure at the moment about queue related methods)

    public function make($name, $value, $minutes = 0, $path = null, $domain = null, $secure = false, $httpOnly = true)
    {
        // check before applying the PREFIX
        if (!empty($name)) {
            $name = PREFIX . $name; // get the PREFIX same way as before
        }

        return parent::make($name, $value, $minutes, $path, $domain, $secure, $httpOnly);
    }
}

更新自己的cookie服务提供者中的代码,以使用您的CookieJar实现(第19行)。

运行$ composer dump-autoload,您就可以完成了。

更新

自从BorisD.Teoharov提出,如果框架在主要版本之间更改了CookieJarStockmake() (或任何其他与cookie相关的函数)的签名,我就做了一个示例存储库,其中包括一个可以按原样使用的测试,如果出现签名更改,它将失败。

它很简单:

代码语言:javascript
运行
复制
public function test_custom_cookie_jar_can_be_resolved()
{
    resolve(\App\Foundation\Cookie\CookieJar::class);
    $this->assertTrue(true);
}

详细说明如何在对应的提交差数中进行检查。

票数 8
EN

Stack Overflow用户

发布于 2018-09-11 23:46:28

我已经设置了测试环境以确保,我没有遗漏任何细节。

在我以前的回答中,我认为使cookie无效对这种情况来说就足够了,但是@BorisD暗示不是这样,我已经在测试中证实了这一点。

所以有一些重要的笔记,来自我的经历.

  1. 不要将Laravel版本混入子域( SESSION_DOMAIN )--如果使用,您需要确保Laravel版本与(根域和子域之间)匹配,因为我已经在example.com域下试验了5.4和dev.example.com下的5.6。这向我展示了在处理Cookies时的一些不一致之处,因此在这些版本之间已经做了一些重要的更改,并且您可以确定如果混合版本,它将不能正常工作。我最终得到了Laravel5.6在两个领域的,所以我不是100%确定这是否在Laravel5.4上有效,但我认为它应该。
  2. 确保您的所有子域都使用相同的APP_KEY -否则,Laravel将无法解密Cookie,返回null值,因为Laravel中的所有加密/解密都使用此应用密钥.
  3. SESSION_DOMAIN.在SESSION_DOMAIN中,我为这两个域指出了相同的根域,如example.com。有了这个设置,我可以在根域上创建一个cookie,并在这两个域中正确地检索它。在该设置之后,在子域上创建cookie也会迫使根域从子域cookie接收新值,并且它们将被重写。所以我想这里的一切都是按照原问题的要求进行的。
  4. Cookie制作参数--如果您想在SESSION_DOMAIN中使用子域,您也可以安全地这样做。但是,您需要确保,重要的是,让我们称它们为全局cookie是以一种稍微不同的方式定义的。Cookie使语法: Cookie make(string $name, string $value, int $minutes, string $path = null, string $domain = null, bool $secure = false, bool $httpOnly = true) 所以这里重要的是,您需要将这个特定cookie的根域放在创建上,例如:return response($content)->cookie('name','value',10,null,'example.com')

结论:

  1. 使用此配置,您应该能够正确地访问子域和根域下的Cookies。
  2. 您可能需要将Laravel安装更新为5.6,这将迫使您至少升级到PHP7.1( PHP中的cookie也有一些更改)
  3. 最后,在您的代码中,不要依赖Cookie的存在,而只依赖它的值(我不知道在您的情况下是否如此)。
票数 2
EN

Stack Overflow用户

发布于 2017-08-22 17:35:05

您可以根据环境设置cookie名称的前缀。

首先,将COOKIE_PREFIX添加到env文件中。

代码语言:javascript
运行
复制
COOKIE_PREFIX=dev

然后,在设置cookie时使用它。

代码语言:javascript
运行
复制
$cookie = cookie(env('COOKIE_PREFIX', 'prod') . '_name', 'value', $minutes);

然后,像这样检索它

代码语言:javascript
运行
复制
$value = $request->cookie(env('COOKIE_PREFIX', 'prod') . '_name');
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45759986

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档