验证FOSUser登录表单中的ReCaptcha


Validate ReCaptcha inside FOSUser login form

我使用FosUserBundleEWZRecaptchaBunde。我覆盖了登录表单以添加recaptcha字段。一切正常。

问题是登录表单验证不考虑reCaptcha字段,如果用户输入正确的登录名和密码,他将被记录。

我已经做了一种预登录事件,应该测试captcha是否有效,但我的预登录是扩展UsernamePasswordFormAuthenticationListenerlistener,我真的不知道如何获得captcha值。

这是覆盖另一个attemptAuthentication方法,在我的pre login listener

protected function attemptAuthentication(Request $request)
{
    // ...
    // I only have added this (return null everytime)
    $captcha = $request->get($this->options['recaptcha'], null, true);
    if ($captcha && true !== $captcha) {
        throw new BadCredentialsException('Invalid captcha.');
    }
    // ...
}

UsernamePasswordFormAuthenticationListener中,他们使用类似$username = $request->get($this->options['username'], null, true);的东西来获得usernamepassword的值。这将从具有_username_password名称的input中获取值(这在侦听器构造函数中定义)。

我尝试使用与其他字段相同的方法来查找验证码值,但验证码字段是div,里面有iframe,所以我每次都得到null,因为它找不到任何东西。

我怎么能得到这个验证码返回的值(真或假,我使用新的验证码)?我真的不知道我应该怎么做才能找到这个值当然如果可能的话。

在登录表单中允许captcha验证可能不是一个好方法。

谢谢你的帮助

如果您实际上想手动检查给定的recaptcha代码是否有效,您可以创建自己的身份验证处理程序。这个处理程序必须实现AuthenticationSuccessHandlerInterfaceAuthenticationFailureHandlerInterface

有两个方法需要实现:'

public function onAuthenticationSuccess(Request $request, TokenInterface $token) {
    // validate captcha code
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception) {
    // validate captcha code
}`

为了使用会话和路由,你需要用ContainerAware扩展处理程序类,然后通过类的构造函数注入这些服务。

将您的自定义处理程序注册为服务:'

...
    #app/config/security.yml
        security.authentication_handler:
            class: AppBundle'Handler'AuthenticationHandler
        public: false
        arguments:
            - @router
            - @session
        calls:
            - [ setContainer, [@service_container ] ]

要启用处理程序,请在security.yml file

中添加以下行

... form_login: success_handler: security.authentication_handler failure_handler: security.authentication_handler

你也可以考虑使用Google reCAPTCHA。