隐藏仅用于Silex中的子请求的路由

时间:2012-06-28 10:01:02

标签: symfony silex

我创建了一条显示网站站点地图的路线sitemap。使用以下Twig构造几乎每个页面都包含此站点地图:

{% if app.debug %}
{{ render(path('sitemap')) }}
{% else %}
<esi:include src="{{ path('sitemap') }}" />
{% endif %}

所以在调试中我也会看到页面。这很完美。虽然,也可以使用/sitemap访问站点地图。我怎么能避免这个?即有没有办法让站点地图路线只能用于子请求?

2 个答案:

答案 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属性以相同的方式保护所有子请求。
  • 您的访问列表中这些元素的顺序很重要。我通常将非常安全的元素放在列表的顶部。