我创建了一条显示网站站点地图的路线sitemap
。使用以下Twig构造几乎每个页面都包含此站点地图:
{% if app.debug %}
{{ render(path('sitemap')) }}
{% else %}
<esi:include src="{{ path('sitemap') }}" />
{% endif %}
所以在调试中我也会看到页面。这很完美。虽然,也可以使用/sitemap
访问站点地图。我怎么能避免这个?即有没有办法让站点地图路线只能用于子请求?
答案 0 :(得分:1)
不知何故,您需要检查当前处理的请求是主请求还是子请求。这是由render正确设置的,然后传递到handle,然后传递到kernel。不幸的是,从控制器(或中间件)获取类型并不容易。
在解析请求之后,但在执行控制器之前,HttpKernel会发出KernelEvents :: CONTROLLER事件。这将获取请求类型。
如果您编写这样的事件监听器,您仍然可以中止:
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
$app["dispatcher"]->addListener(KernelEvents::CONTROLLER, function (FilterControllerEvent $event) use ($app) {
$internals = array("sitemap");
$route = $event->getRequest()->get("_route");
if (in_array($route, $internals) && $event->getRequestType() == HttpKernelInterface::SUB_REQUEST) {
return $app->abort(403);
}
});
答案 1 :(得分:1)
将此项添加到security.yml
文件将允许您保护控制器:
access_control:
- { path: ^/private, roles: IS_AUTHENTICATED_ANONYMOUSLY, ip: 127.0.0.1 }
- { path: ^/private, roles: ROLE_NO_ACCESS }
然后将您的控制器置于以/private
:
<route id="whatever" pattern="/private/sitemap">
<default key="_controller">AcmeDemoBundle:Sitemap:whatever</default>
</route>
这是保护所有以/private
开头的子请求的一般方法,以便人们无法访问/private/sitemap
。嵌入控制器将起作用,因为服务器(127.0.0.1
通过环回接口)将发出请求。
/private
属性以相同的方式保护所有子请求。