如何摆脱 GET 请求的 "You must configure the check path to be handled by the firewall" 错误?

How to get rid of "You must configure the check path to be handled by the firewall" error with GET requests?

当我以通常的方式(使用登录表单)进行身份验证时,它工作正常。只有当直接通过 GET 方法访问 /check_form 时,我才会收到此错误,在这种情况下会抛出异常:

You must configure the check path to be handled by the firewall using form_login in your security firewall configuration.

这是相关的 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 请求由控制器处理。因此,似乎必须扩展默认 checkAction() 才能处理两种情况:

  1. 当请求为 POST 但不存在防火墙条目时(已处理)
  2. 存在防火墙条目但请求为 GET(我的情况)

没有配置选项。如果请求到达控制器,则无条件抛出异常:credible source.

POST 对路由的请求由防火墙处理:official docsGET 像往常一样去控制器。

如果您不关心此类事件,则有几个选项可以消除日志中的错误。在我看来,最简单的方法是覆盖 SecurityController::checkAction 到 return 500 错误而不抛出异常。官方文档是如何实现的:Overriding Default FOSUserBundle Controllers.

编辑:

在控制器中你可以return任何你喜欢的代码:

public function checkAction()
{
    return new Response('', 418); // or better use Response constants 
}

另一种方法是在路由配置中禁用 /acme/login_check 的 GET 方法,让路由器像往常一样完成它的工作和 return 正常 405 Method Not Allowed

编辑2:

可以在action中分析request,还是抛出异常:

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);
    }
}

但我建议改为调试您的路由。这个逻辑应该属于路由器,而不是控制器。在漫长的 运行 中,您的路由配置会误导维护此代码的开发人员,并且他们将花费数小时的艰苦调试时间试图弄清楚为什么 returns 405,当 app/console debug:router 明确指出 GET 方法是允许的。