RR4*_*404 7 config dynamic symfony
我有一个可以为多个域提供服务的应用.我遇到了问题framework.session.cookie_domain
我有一个问题是我想动态设置cookie_domain参数,因为我事先不知道请求来自哪个域.
AppKernel.php这样做:$domain = substr($_SERVER['HTTP_HOST'], strpos($_SERVER['HTTP_HOST'], '.'));
ini_set('session.cookie_domain', $domain);
我可以config.yml为每个域有多个,但我想避免这种情况.
你知道吗?
谢谢
RR4*_*404 10
好的,我已经弄明白了.
这并不困难.
我创建了一个自定义sessionStorage,扩展了默认的一个,我做了一个简单的覆盖,其中选项正在处理:我计算了我的cookie_domain并将其传递给parent :: function:
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
/**
* DynamicDomainSessionStorage.
*
* @author Julien Devouassoud
*/
class DynamicDomainSessionStorage extends NativeSessionStorage
{
/**
* setOptions.
*
* {@inheritDoc}
*/
public function setOptions(array $options)
{
if(isset($_SERVER['HTTP_HOST'])){
$domain = substr($_SERVER['HTTP_HOST'], strpos($_SERVER['HTTP_HOST'], '.'));
$options["cookie_domain"] = $domain;
}
return parent::setOptions($options);
}
}
Run Code Online (Sandbox Code Playgroud)
别忘了:
•将您的班级声明为服务
•将此服务设置为存储
•设置save_path,否则cookie_domain似乎不起作用(打破会话)
•我也设置了"名称",但我认为这不是必需的
•代码config.yml:
#...
framework:
#...
session:
storage_id: v3d.session.storage.dynamic_domain
save_path: %kernel.root_dir%/cache/var/sessions
name: SFSESSID
services
v3d.session.storage.dynamic_domain:
class: V3d\Bundle\ApplicationBundle\Services\DynamicDomainSessionStorage
Run Code Online (Sandbox Code Playgroud)
tet*_*anz 10
我有类似的情况.这是一个拥有学区和学校的多租户网站.每个学区和学校都有自己的URL,如下所示:
我希望用户只需一次登录即可访问一个地区的所有学校.因此,我需要将cookie放在地区一级.
这是我的会话存储服务.
namespace AppBundle\Services;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
class MySessionStorage extends NativeSessionStorage
{
public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null, RequestStack $requestStack)
{
$host = $requestStack->getMasterRequest()->getHost();
$options['cookie_domain'] = substr($host, strpos($host, '.') + 1);
parent::__construct($options, $handler, $metaBag);
}
}
Run Code Online (Sandbox Code Playgroud)
在services.yml中
mySessionStorage:
class: AppBundle\Services\MySessionStorage
arguments: [%session.storage.options%, @session.handler, @session.storage.metadata_bag, @request_stack]
Run Code Online (Sandbox Code Playgroud)
在框架下的config.yml中:
session:
handler_id: session.handler.native_file
storage_id: mySessionStorage
Run Code Online (Sandbox Code Playgroud)
请注意,在标准Symfony安装中,handler_id默认为null(〜).需要将其设置为服务接收非null @ session.handler的内容.
这是为会话cookie做的,但我需要更改的另一个是remember_me cookie.您可以在config.yml中将域设置为常量,但我需要它依赖于主机.也许我错过了一些东西,但我无法在安全系统中看到一种动态的方法.RememberMeFactory直接实例化,而不是通过配置.我的解决方案是监听kernel.response并在发送之前替换cookie.
namespace AppBundle\Listeners;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
class CookieFix
{
private $requestStack;
public function __construct(RequestStack $requestStack)
{
$this->requestStack = $requestStack;
}
public function onKernelResponse(FilterResponseEvent $event)
{
$response = $event->getResponse();
$cookies = $response->headers->getCookies();
$rMe = null;
foreach($cookies as $cookie) {
/** @var \Symfony\Component\HttpFoundation\Cookie $cookie */
if ($cookie->getName() == 'REMEMBERME') {
$rMe = $cookie;
break;
}
}
if ($rMe !== null) {
$host = $this->requestStack->getMasterRequest()->getHost();
$newDomain = substr($host, strpos($host, '.') + 1);
$response->headers->removeCookie($rMe->getName());
$response->headers->setCookie(new Cookie($rMe->getName(), $rMe->getValue(), $rMe->getExpiresTime(), $rMe->getPath(), $newDomain));
}
}
}
Run Code Online (Sandbox Code Playgroud)
我应该尝试从配置中获取cookie名称.
在services.yml中
cookieFix:
class: AppBundle\Listeners\CookieFix
arguments: [@request_stack]
tags:
- { name: kernel.event_listener, event: kernel.response, method: onKernelResponse, priority: -100 }
Run Code Online (Sandbox Code Playgroud)
-100优先级确保它在创建cookie的侦听器之后运行.