当设备禁用cookie时,Symfony2解决方法

时间:2014-11-25 20:56:53

标签: php symfony session cookies

对于项目,我需要为访问者提供持久会话。 几年前,我遇到了苹果更新临时渲染所有iPhone无法设置PHPSESSID cookie的问题。

我创建了一个回退方法,该方法检查URL中的SESSION ID,并使用它来持久保存请求之间的会话。我知道这可以使用session.use_trans_sid在php.ini中启用。

重点是我不希望这种情况一直发生。如果可能,我更喜欢cookie方法。 Symfony中是否有办法将此逻辑添加到添加会话标识符的路由方法中?

任何人都可以帮我解释在哪里扩展twig“path”方法来添加逻辑,以便可选地将会话ID附加到该方法生成的所有URL。

更新

让我发布一个关于我的进展的更新,也许有人可以帮助我。我设法通过替换参数中的generator_base_class来找到如何使用我自己的代码扩展UrlGenerator。

现在我有以下问题。 我希望使用一个会话来做一些逻辑。但是我无法将此核心组件作为服务来实现。我已经尝试为UrlGenerator和扩展的Router类设置一个compilerPass,以便能够在其中一个类中进行依赖注入。

然而直到现在它遗憾地失败了。 在UrlGenerator类中获取Session组件的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

由于这篇文章,我能够创建我的解决方案: Override router and add parameter to specific routes (before path/url used)

最后这是我提出的代码。

In my service.xml

<parameters>
    <parameter key="router.class">Acme\CoreBundle\Component\Routing\Router</parameter>
    <parameter key="router.options.generator_base_class">Acme\CoreBundle\Component\Routing\Generator\UrlGenerator</parameter>
</parameters>

扩展Symfony的核心路由器以在ContainerAware中生成并强制该容器到UrlGenerator。

namespace Acme\CoreBundle\Component\Routing;

use Symfony\Bundle\FrameworkBundle\Routing\Router as BaseRouter;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Routing\RequestContext;

class Router extends BaseRouter implements ContainerAwareInterface
{
    private $container;

    public function __construct(ContainerInterface $container, $resource, array $options = array(), RequestContext $context = null)
    {
        parent::__construct($container, $resource, $options, $context);
        $this->setContainer($container);
    }

    public function getGenerator()
    {
        $generator = parent::getGenerator();
        $generator->setContainer($this->container);
        return $generator;
    }

    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }
}

扩展UrlGenerator类。

namespace Acme\CoreBundle\Component\Routing\Generator;

use Symfony\Component\Routing\Generator\UrlGenerator as BaseUrlGenerator;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * UrlGenerator generates URL based on a set of routes, this class extends the basics from Symfony.
 */
class UrlGenerator extends BaseUrlGenerator implements ContainerAwareInterface
{
    private $container;

    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }

    protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, array $requiredSchemes = array())
    {
        /** @var \Symfony\Component\HttpFoundation\Session\Session $session */
        $session = $this->container->get('session');
        if (true !== $session->get('acceptCookies')) {
            $parameters[$session->getName()] = $session->getId();
        }

        return parent::doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, $requiredSchemes);
    }
}

最后,当会话值acceptCookies不等于true时,会导致会话名称和id被附加到生成的URL。