将Captcha添加到Symfony2登录

时间:2016-07-21 23:34:18

标签: php validation symfony login captcha

我需要将Captcha添加到我的登录页面,我正在使用GregwarCaptchaBundle和FosUserBundle。

目前,我已使用以下代码在登录时显示验证码:

<?php

/*
 * This file is part of the FOSUserBundle package.
 *
 * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace FOS\UserBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Gregwar\Captcha\CaptchaBuilder;

class SecurityController extends Controller
{
    public function loginAction(Request $request)
    {
        $builtCaptcha = new CaptchaBuilder();
        $builtCaptcha->build();
        $builtCaptcha->save('captcha.jpg');
        /** @var $session \Symfony\Component\HttpFoundation\Session\Session */
        $session = $request->getSession();

        if (class_exists('\Symfony\Component\Security\Core\Security')) {
            $authErrorKey = Security::AUTHENTICATION_ERROR;
            $lastUsernameKey = Security::LAST_USERNAME;
        } else {
            // BC for SF < 2.6
            $authErrorKey = SecurityContextInterface::AUTHENTICATION_ERROR;
            $lastUsernameKey = SecurityContextInterface::LAST_USERNAME;
        }

        // get the error if any (works with forward and redirect -- see below)
        if ($request->attributes->has($authErrorKey)) {
            $error = $request->attributes->get($authErrorKey);
        } elseif (null !== $session && $session->has($authErrorKey)) {
            $error = $session->get($authErrorKey);
            $session->remove($authErrorKey);
        } else {
            $error = null;
        }

        if (!$error instanceof AuthenticationException) {
            $error = null; // The value does not come from the security component.
        }

        // last username entered by the user
        $lastUsername = (null === $session) ? '' : $session->get($lastUsernameKey);

        if ($this->has('security.csrf.token_manager')) {
            $csrfToken = $this->get('security.csrf.token_manager')->getToken('authenticate')->getValue();
        } else {
            // BC for SF < 2.4
            $csrfToken = $this->has('form.csrf_provider')
                ? $this->get('form.csrf_provider')->generateCsrfToken('authenticate')
                : null;
        }
        $t = $request->get('_captcha');
        if($t!=$builtCaptcha){
            echo 'error';
        }
        var_dump($t);

        return $this->renderLogin(array(
            'last_username' => $lastUsername,
            'error' => $error,
            'csrf_token' => $csrfToken,
            'captcha' => $builtCaptcha,
        ));
    }

    /**
     * Renders the login template with the given parameters. Overwrite this function in
     * an extended controller to provide additional data for the login template.
     *
     * @param array $data
     *
     * @return \Symfony\Component\HttpFoundation\Response
     */
    protected function renderLogin(array $data)
    {
        return $this->render('FOSUserBundle:Security:login.html.twig', $data);
    }

    public function checkAction($builtCaptcha)
    {
            return $this->redirect($this->generateUrl('fos_user_login'));
        }
        throw new \RuntimeException('You must configure the check path to be handled by the firewall using form_login in your security firewall configuration.');
    }

    public function logoutAction()
    {
        throw new \RuntimeException('You must activate the logout in your security firewall configuration.');
    }
}

我已经覆盖了登录和注册模板作为文档说明(注册与验证码一起工作正常)

问题在于我不知道如何验证验证码的代码。

我想我应该把它放到checkAction()

但我不确定,我很抓到这个问题。

如果有人能帮助我,我将非常感激,提前致谢。

1 个答案:

答案 0 :(得分:3)

在尝试将Google ReCaptcha实现为带有数据库提供程序的简单登录表单时,我遇到了同样的问题。这是一个基于SecurityEvents :: INTERACTIVE_LOGIN触发的侦听器的工作解决方案。在验证凭据之后但在重定向到security.yml中定义的default_target_path之前,会触发此事件。

注意:该示例与其他一些功能混合在一起,因为我也在捕获失败的登录尝试。

import socket

server,port = 'google.com',80
ip = socket.gethostbyname(server)
print (ip)
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect((server,port))
request = 'GET /HTTP/1.1\nHost: '+str(ip)+'\n\n'
print(request)
sock.sendall(request.encode())
while True:
   data = ' '
   data = sock.recv(4096)
   if data == ' ':
       break
    print(data.decode())

希望有帮助...