2

我正在设置允许以下路由的路由:

/client_a/dashboard/
/client_b/dashboard/

我在我的中使用了一个app/config/routing.yml看起来像这样的前缀:

AcmeMainBundle:
    resource: "@AcmeMainBundle/Resources/config/routing.yml"
    prefix:   /{client}  

我遇到的问题是登录路由似乎有前缀问题。这是我/Resources/config/routing.yml正在导入主路由文件中的条目:

acme_login:
    pattern: /login/
    defaults: {_controller: AcmeMainBundle:Main:login }

acme_login_check:
    pattern: /login_check
    # defaults: This is not required since the Firewall will handle this

acme_logout:
    pattern: /logout/
    # defaults: This is not required since the Firewall will handle this

登录页面显示正常,但在用户提交登录页面后,Symfony 会抛出错误说明:

Unable to find the controller for path "/client_a/login_check". Maybe you forgot to add the matching route in your routing configuration?

在我看来,Symfony2 在内部安全路由和在 routing.yml 中使用前缀时遇到了困难。

有什么办法可以克服这个问题?

注意:解决此问题的一种方法是更改​​我的 routing.yml 文件中的所有路由以包含 {client} 参数。唯一的问题是,这是一个非常广泛的应用程序,包含大量路线。使用前缀可以创造奇迹,除了登录期间的安全处理。

谢谢,

JB

4

3 回答 3

1

您需要的可能解决方案是:

文件:src/Acme/CoreBundle/Twig/PathExtension.php

<?php

namespace Acme\CoreBundle\Twig\Extension;

use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernel;

class PathExtension extends \Twig_Extension
{

    private $request;
    private $router;

    public function __construct(Router $router) {
        $this->router = $router;
    }

    public function onKernelRequest(GetResponseEvent $event) {
        if ($event->getRequestType() === HttpKernel::MASTER_REQUEST) {
            $this->request = $event->getRequest();
        }
    }

    public function getFunctions()
    {
        return array(
            'path_route' => new \Twig_Function_Method($this, 'getPath')
        );
    }

    public function getPath($name, $parameters = array())
    {
        $parameters = array_merge($parameters, [
            'client' => $this->request->get('client'),
        ]);

        return $this->router->generate($name, $parameters, false);
    }

    public function getName()
    {
        return 'twig_path_route_extension';
    }

}

配置即服务:

文件:src/Acme/CoreBundle/Resources/config/services.yml

services:
    twig.path_route_extension:
        class: Acme\CoreBundle\Twig\PathExtension
        tags:
            - { name: twig.extension }
            - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
        arguments: [@router]

设置您的路由选项:

文件:app/config/routing.yml

_acme_client:
    resource: "@AcmeCoreBundle/Resources/config/routing.yml"
    prefix:   /{client}/

然后你可以在模板和 routing.yml 中使用它,例如:

_acme_client_dashboard:
    path:     /dashboard
    defaults: { _controller: AcmeCoreBundle:System:dashboard }

然后,在您的模板中,您可以使用:

<a href="{{ path_route('_acme_client_dashboard') }}">
  Link to Dashboard.
</a>

参考:

自动传递路径参数

http://blog.viison.com/post/15619033835/symfony2-twig-extension-switch-locale-current-route

于 2014-07-10T03:31:30.913 回答
0

我认为您可能需要在这些路由上定义一个控制器defaults: {_controller: AcmeMainBundle:Main:login }。在默认情况下它不需要它们,因为防火墙在路由之前捕获它。但在这种情况下可能需要它来匹配前缀。

于 2012-07-10T03:52:54.807 回答
0

经过相当多的研究和不同方面的尝试,目前在路由中使用动态前缀似乎没有好的解决方案。

问题似乎是安全包在路由发生之前执行其代码,因此前缀中的路由属性在 security.yml 中不可用,而是静态路径。这本身就引起了问题,因为 Symfony 然后抱怨缺少属性等。

所以,答案是,结合安全实现,以上是不可能的,至少不是我发现的方式。

于 2012-07-11T02:28:55.860 回答