当我以通常的方式(使用登录表单)进行身份验证时,它可以正常工作。只有当通过GET方法直接访问/check_form
时,我才会得到这个错误,在这种情况下会抛出异常:
您必须在安全防火墙配置中使用form_login配置要由防火墙处理的检查路径。
以下是相关的security.yml
部分:
firewalls:
acme_area:
pattern: ^/(acme|admin)/
provider: fos_userbundle
form_login:
provider: fos_userbundle
csrf_provider: form.csrf_provider
login_path: acme_login
check_path: /acme/login_check
logout:
path: /acme/logout
target: acme_login
anonymous: true
我使用的是2.3,因此没有适用的methods
选项(尽管我不知道它是否有帮助)。
这并不是一个真正的问题,因为这个错误不会破坏正确的使用,但当一些勤奋的机器人访问网站时,它会污染错误日志,而且它只是不整洁。所以,我想知道我可以更改哪个配置选项来消除这个错误。
简而言之,我似乎希望抛出一些4xx错误,而不是500。理想情况下应该是405 Method Not Allowed
,但404
冷也可以。
编辑:
正如我从下面Alex的回答中了解到的那样,之所以会发生这种情况,是因为POST请求由防火墙处理,GET请求由Controller处理。因此,似乎必须扩展默认checkAction()
才能处理两种情况:
- 当请求是POST但不存在防火墙条目时(已禁用)
- 当防火墙条目存在但请求为GET时(我的情况)
没有配置选项。如果请求到达控制器,则无条件抛出异常:可信源。
POST
对路由的请求由防火墙处理:官方文档;GET
和往常一样进入控制器。
如果您不关心此类事件,那么几乎没有选项可以消除日志中的错误。在我看来,最简单的方法是重写SecurityController::checkAction
以返回500错误,而不引发异常。官方文档介绍了如何实现:覆盖默认FOSUserBundle控制器。
编辑:
在控制器中,您可以返回任何您喜欢的代码:
public function checkAction()
{
return new Response('', 418); // or better use Response constants
}
另一种方法是在路由配置中禁用对/acme/login_check
的GET方法,让路由器完成它的工作并像往常一样返回正常的405 Method Not Allowed
。
第2版:
您可以在操作中分析请求,但仍然抛出异常:
public function checkAction(Request $request)
{
if ($request->getMethod() == Request::METHOD_POST) {
throw new RuntimeException('You must configure the check path to be handled by the firewall using form_login in your security firewall configuration.');
} else {
return new Response('', Response::HTTP_METHOD_NOT_ALLOWED);
}
}
但我建议您改为调试路由。这个逻辑应该属于路由器,而不是控制器。从长远来看,您的路由配置会误导维护此代码的开发人员,他们将花几个小时的时间进行艰难的调试,试图弄清楚为什么它会返回405
,而app/console debug:router
明确表示允许使用GET
方法。