在symfony2中覆盖GET请求的HTTP方法

时间:2014-11-14 18:00:45

标签: php symfony

我正在阅读"用_method"伪造方法。以下网址的部分: http://symfony.com/doc/current/cookbook/routing/method_parameters.html

经过一些实验,我意识到文档不清楚或不准确。 如果浏览器使用 POST (而非GET)发出请求,则只能使用 _method 参数覆盖HTTP方法。

的Symfony \元器件\ HttpFoundation \请求

public function getMethod()
    {
        if (null === $this->method) {
            $this->method = strtoupper($this->server->get('REQUEST_METHOD', 'GET'));

            if ('POST' === $this->method) {
                if ($method = $this->headers->get('X-HTTP-METHOD-OVERRIDE')) {
                    $this->method = strtoupper($method);
                } elseif (self::$httpMethodParameterOverride) {
                    $this->method = strtoupper($this->request->get('_method', $this->query->get('_method', 'POST')));
                }
            }
        }

        return $this->method;
    }

在我们的应用程序中,我们希望覆盖GET请求的HTTP方法,因为我们正在使用JSONP。 在我们的示例中,这不是安全问题,因为请求是使用CSRF令牌签名的。

我在"覆盖请求"中找到了解决方案。部分:

http://symfony.com/doc/current/components/http_foundation/introduction.html

这将涉及创建Symfony \ Component \ HttpFoundation \ Request的子类,覆盖getMethod()方法,并使用Request :: setFactory()进行设置。

use Symfony\Component\HttpFoundation\Request;

Request::setFactory(function (
    array $query = array(),
    array $request = array(),
    array $attributes = array(),
    array $cookies = array(),
    array $files = array(),
    array $server = array(),
    $content = null
) {
    return SpecialRequest::create(
        $query,
        $request,
        $attributes,
        $cookies,
        $files,
        $server,
        $content
    );
});

$request = Request::createFromGlobals();

我的问题是:

我唯一可以看到这样做的地方是app.php / app_dev.php / app_test.php。 E.g:

require_once __DIR__.'/../app/AppKernel.php';

$kernel = new AppKernel($env, $is_debug);
$kernel->loadClassCache();

// When using the HttpCache, you need to call the method in your front controller instead of relying on the configuration parameter
//Request::enableHttpMethodParameterOverride();
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);

这是否适合这样做?

我查看了内核事件,例如kernel.request,但此时此事件似乎为时已晚:

" 1)kernel.request事件 典型目的:向Request添加更多信息,初始化系统的各个部分,或者尽可能返回Response(例如拒绝访问的安全层)。"

http://symfony.com/doc/current/components/http_kernel/introduction.html

任何建议都将不胜感激。谢谢。

2 个答案:

答案 0 :(得分:1)

要覆盖symfony中的HTTP方法,它并不难,首先将参数方法添加到路由中:

blog_update:
    path:     /blog/{slug}
    defaults: { _controller: AcmeDemoBundle:Blog:update }
    methods:   [PUT]

接下来,根据您使用的symfony版本,启用Http方法参数覆盖,以及如何执行此操作:(来自symfony doc)

The _method functionality shown here is disabled by default in Symfony 2.2 and enabled by default in Symfony 2.3. To control it in Symfony 2.2, you must call Request::enableHttpMethodParameterOverride before you handle the request (e.g. in your front controller). In Symfony 2.3, use the http_method_override option.

现在,如果您使用的是symfony的FormBuilder,它应该添加名为" _method"的隐藏输入,或者如果您不使用symfony,则可以自己添加它表单构建器。

这里是完整的文档:http://symfony.com/doc/current/cookbook/routing/method_parameters.html

答案 1 :(得分:0)

要在symfony中启用HTTP方法的覆盖,您应该在config.yml中定义http_method_override

framework:
    http_method_override: true

kernel.http_method_override