如何在Laravel 5.5中重写Cookie构造函数以支持iframe内嵌站点
完全可以通过扩展Symfony的Cookie类,替换Laravel默认的CookieJar实现来解决这个问题,不用修改vendor目录代码,步骤如下:
1. 创建自定义Cookie类
在app/Http目录下新建CustomCookie.php,继承Symfony原生Cookie类,重写构造函数放宽SameSite选项的验证:
<?php namespace App\Http; use Symfony\Component\HttpFoundation\Cookie as SymfonyCookie; class CustomCookie extends SymfonyCookie { public function __construct( string $name, string $value = null, int $expire = 0, string $path = '/', string $domain = null, bool $secure = false, bool $httpOnly = true, bool $raw = false, string $sameSite = null ) { $this->name = $name; $this->value = $value; $this->expire = $expire; $this->path = $path; $this->domain = $domain; $this->secure = $secure; $this->httpOnly = $httpOnly; $this->raw = $raw; // 新增允许`none`作为SameSite值 if (!in_array($sameSite, ['lax', 'strict', 'none', null], true)) { throw new \InvalidArgumentException('The "sameSite" parameter must be "lax", "strict", "none", or null.'); } $this->sameSite = $sameSite; } }
2. 扩展Laravel的CookieJar
在app/Http目录下新建CustomCookieJar.php,重写make方法来生成我们自定义的Cookie实例:
<?php namespace App\Http; use Illuminate\Cookie\CookieJar as IlluminateCookieJar; class CustomCookieJar extends IlluminateCookieJar { public function make($name, $value = null, $minutes = 0, $path = null, $domain = null, $secure = null, $httpOnly = true, $raw = false, $sameSite = null) { $config = $this->config->get('session'); // 沿用Laravel默认的配置逻辑 $path = is_null($path) ? $config['path'] : $path; $domain = is_null($domain) ? $config['domain'] : $domain; $secure = is_null($secure) ? $config['secure'] : $secure; // 返回自定义Cookie实例 return new CustomCookie( $name, $value, $this->getTimestamp($minutes), $path, $domain, $secure, $httpOnly, $raw, $sameSite ); } }
3. 替换默认的Cookie服务提供者
在app/Providers目录下新建CustomCookieServiceProvider.php,替换原生的Cookie服务提供者逻辑:
<?php namespace App\Providers; use App\Http\CustomCookieJar; use Illuminate\Cookie\CookieServiceProvider as IlluminateCookieServiceProvider; class CustomCookieServiceProvider extends IlluminateCookieServiceProvider { public function register() { $this->app->singleton('cookie', function ($app) { return new CustomCookieJar($app['config'], $app['request']); }); } }
4. 配置启用自定义服务提供者
打开config/app.php,在providers数组中替换原生的Cookie服务提供者:
// 注释掉原有的服务提供者 // Illuminate\Cookie\CookieServiceProvider::class, // 添加自定义的服务提供者 App\Providers\CustomCookieServiceProvider::class,
5. 使用支持SameSite=None的Cookie
现在就可以正常设置SameSite: none的Cookie了,注意SameSite=None必须配合Secure属性使用:
// 控制器中设置Cookie return response('内容')->cookie( 'cookie_name', 'cookie_value', 60, '/', null, true, true, false, 'none' ); // 或者使用Cookie门面 Cookie::queue('cookie_name', 'cookie_value', 60, '/', null, true, true, false, 'none');
内容的提问来源于stack exchange,提问作者Barnaby
相关产品推荐
相关产品推荐

