Php 覆盖symfony2中GET请求的HTTP方法
我正在阅读以下URL上的“用_方法伪造方法”部分: 经过一些实验,我意识到文档要么不清楚,要么不准确。 如果浏览器使用POST(而不是GET)发出请求,则只能使用\u method参数覆盖HTTP方法 Symfony\Component\HttpFoundation\RequestPhp 覆盖symfony2中GET请求的HTTP方法,php,symfony,Php,Symfony,我正在阅读以下URL上的“用_方法伪造方法”部分: 经过一些实验,我意识到文档要么不清楚,要么不准确。 如果浏览器使用POST(而不是GET)发出请求,则只能使用\u method参数覆盖HTTP方法 Symfony\Component\HttpFoundation\Request public function getMethod() { if (null === $this->method) { $this->method = s
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令牌签名的
我在这里的“覆盖请求”部分找到了解决方案:
这将涉及生成Symfony\Component\HttpFoundation\Request的子类,覆盖getMethod()方法,并使用Request::setFactory()进行设置
我的问题是:
我唯一可以看到的地方是app.php/app_dev.php/app_test.php。例如:
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事件
典型用途:向请求添加更多信息、初始化部分系统或返回响应(如拒绝访问的安全层)。”
如有任何建议,将不胜感激。谢谢。要覆盖symfony中的HTTP方法,并不难,首先将参数方法添加到路由中:
blog_update:
path: /blog/{slug}
defaults: { _controller: AcmeDemoBundle:Blog:update }
methods: [PUT]
接下来,根据您使用的symfony的版本,启用Http方法参数覆盖,下面是如何做到这一点:(来自symfony doc)
此处显示的_方法功能在Symfony 2.2中默认禁用,在Symfony 2.3中默认启用。要在Symfony 2.2中对其进行控制,必须在处理请求之前(例如在前端控制器中)调用Request::enableHttpMethodParameterOverride。在Symfony 2.3中,使用http方法覆盖选项。
现在,如果您正在使用symfony的FormBuilder,它应该添加一个名为“\u method”的隐藏输入,或者如果您不使用symfony的form builder,您可以自己添加它
下面是完整的文档:要在symfony中启用HTTP方法覆盖,您应该在config.yml中定义HTTP方法覆盖
framework:
http_method_override: true
覆盖请求对象
对于那些对重写请求
基类感兴趣的人
实际上,文件中有一个错误,我将为此发送一份PR
以下(参见您的示例)不正确:
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();
以下是正确的:
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 new SpecialRequest(
$query,
$request,
$attributes,
$cookies,
$files,
$server,
$content
);
});
$request = Request::createFromGlobals();
你能看出区别吗
- 请查看并签名
static public enableHttpMethodParameterOverride()启用对_method请求参数的支持,以确定预期的HTTP方法。请注意,启用此功能可能会导致代码中出现CSRF问题。检查您是否在需要时使用CSRF令牌。只有当真正的HTTP方法是POST时,才能覆盖HTTP方法。
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 new SpecialRequest(
$query,
$request,
$attributes,
$cookies,
$files,
$server,
$content
);
});
$request = Request::createFromGlobals();