我正在设置允许以下路由的路由:
/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
答案 0 :(得分: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>
参考文献:
Pass path parameters automatically
http://blog.viison.com/post/15619033835/symfony2-twig-extension-switch-locale-current-route
答案 1 :(得分:0)
我认为您可能需要在defaults: {_controller: AcmeMainBundle:Main:login }
的路线上定义控制器。它在默认情况下不需要它们,因为防火墙在路由之前捕获它。但在这种情况下可能需要它来匹配前缀。
答案 2 :(得分:0)
经过相当多的研究和尝试不同的方面,此时在路由中使用动态前缀似乎没有好的解决方案。
问题似乎是安全包在路由发生之前执行其代码,因此来自前缀的路由属性在security.yml中不可用,而是相当静态的路径。这本身就是导致问题,因为Symfony然后抱怨缺少属性等等。
所以,答案是,结合安全实施,上述是不可能的,至少不是我发现的方式。