添加验证码到 Symfony2 登录

2024-05-27

我需要将验证码添加到我的登录页面,我正在使用 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() 中执行此操作

但我不确定,我很困惑这个问题。

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


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

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

<?php

namespace ExampleBundle\EventListener;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
use Symfony\Component\Security\Core\AuthenticationEvents;
use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent;
use Symfony\Component\Security\Core\Event\AuthenticationEvent;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
use ExampleBundle\Google\GoogleReCaptcha;
use Doctrine\ORM\EntityManager;
use ExampleBundle\Entity\User;

/**
 * Class AuthenticationAttemptListener
 * @package ExampleBundle\EventListener
 */
class AuthenticationAttemptListener implements EventSubscriberInterface
{
    /**
     * @var EntityManager
     */
    private $entityManager;

    /**
     * @var GoogleReCaptcha
     */
    private $googleReCaptcha;

    /**
     * @var integer
     */
    private $maxFailedLoginAttempts;

    /**
     * AuthenticationAttemptListener constructor.
     *
     * @param EntityManager $entityManager
     * @param GoogleReCaptcha $googleReCaptcha
     * @param integer $maxFailedLoginAttempts
     */
    public function __construct(EntityManager $entityManager, GoogleReCaptcha $googleReCaptcha, $maxFailedLoginAttempts)
    {
        $this->entityManager = $entityManager;
        $this->googleReCaptcha = $googleReCaptcha;
        $this->maxFailedLoginAttempts = $maxFailedLoginAttempts;
    }

    /**
     * @return array
     */
    public static function getSubscribedEvents()
    {
        return array(
            AuthenticationEvents::AUTHENTICATION_FAILURE => 'onAuthenticationFailure',
            AuthenticationEvents::AUTHENTICATION_SUCCESS => 'onAuthenticationSuccess',
            SecurityEvents::INTERACTIVE_LOGIN => 'onInteractiveLogin'
        );
    }

    /**
     * Count failed login attempts and save to database on existing usernames
     *
     * @param AuthenticationFailureEvent $event
     */
    public function onAuthenticationFailure(AuthenticationFailureEvent $event)
    {
        if ($event->getAuthenticationException() instanceof BadCredentialsException) {

            $databaseUser = $this->searchUserinDatabase($event);

            // increase failed attempt counter or lock-up account
            if ($databaseUser !== null) {
                if (!$databaseUser->isEnabled()) {
                    throw new CustomUserMessageAuthenticationException('user_deactivated');
                } else {
                    $databaseUser->increaseFailedLoginAttempts();
                    $databaseUser->setFailedLoginLastTimestamp(new \DateTime());
                    if ($databaseUser->getFailedLoginAttempts() == $this->maxFailedLoginAttempts) {
                        $databaseUser->setIsActive(0);
                    }

                    $this->entityManager->persist($databaseUser);
                    $this->entityManager->flush();
                }
            }
        }
    }

    /**
     * @param AuthenticationSuccessEvent $event
     */
    public function onAuthenticationSuccess(AuthenticationEvent $event)
    {
        // Attention: Event will be thrown on every request if you have session-based authentication!
        // Reset of attempt counter may occur if user is logged in while brute force attack is running
    }

    /**
     * Check incoming google recaptcha token and reset attempt-counter on success or throw exception
     *
     * @param InteractiveLoginEvent $event
     */
    public function onInteractiveLogin(InteractiveLoginEvent $event)
    {
        $reCaptchaResponse = $event->getRequest()->get('g-recaptcha-response');
        $captchaRequest = $this->googleReCaptcha->checkReCaptcha($reCaptchaResponse);

        if (is_array($captchaRequest) && $captchaRequest['success'] === true) {
            // reset attempt counter because of successful login and positive recaptcha response
            $databaseUser = $this->searchUserinDatabase($event);

            if ($databaseUser !== null && $databaseUser->isEnabled()) {
                $databaseUser->setFailedLoginAttempts(null);
                $databaseUser->setFailedLoginLastTimestamp(null);

                $this->entityManager->persist($databaseUser);
                $this->entityManager->flush();
            }
        } else {
            // on all other recaptcha related errors throw exception
            throw new CustomUserMessageAuthenticationException('recaptcha_error');
        }
    }

    /**
     * Retrieve user from database
     *
     * @param AuthenticationFailureEvent|AuthenticationEvent $event
     *
     * @return User|null
     */
    private function searchUserinDatabase($event)
    {
        $token = $event->getAuthenticationToken();
        $username = $token->getUsername();
        $databaseUser = null;

        if (!$token instanceof AnonymousToken) {
            // get user from database
            $databaseUser = $this->entityManager->getRepository($entity)->findOneBy(array(
                "username" => $username
            ));
        }

        return $databaseUser;
    }
}

希望有帮助...

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

添加验证码到 Symfony2 登录 的相关文章

  • 免费 PHP 登录库 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • setcookie with expire=0 浏览器关闭后不会过期

    我使用setcookie来制作一个过期 0的cookie 从 PHP 文档来看 link http php net manual en function setcookie php cookie 过期的时间 这是一个 Unix 时间戳 所以
  • 获取 YouTube 最高缩略图分辨率

    我想获得 youtube 最高缩略图 maxresdefault jpg 像这个 http i ytimg com vi Cj6ho1 G6tw maxresdefault jpg http i ytimg com vi Cj6ho1 G6
  • 将 PHP 短开放标签替换为

    我有大量多年来编写的 php 文件 我需要将所有短开放标签正确替换为正确的显式开放标签 change
  • Yii2 - 错误请求 (#400) |前端和后端cookie

    仅当我打开时才会出现此问题frontend and backend在相同的browser 设想 与后端交互 gt 切换选项卡 gt 与前端交互 gt 切换选项卡返回 gt 与后端交互 gt 错误请求 400 Cookie 后端 identi
  • PHP WCF 集成

    是不是如果我想支持php客户端访问我的服务 我必须有一个基本的http端点 这是因为php仍然只支持soap 1 1吗 据我所知 自从我使用 PHP 以来已经两年了 情况仍然如此 如果客户端应用程序将使用 PHP 的内置 SoapClien
  • PHP:读取所有传入 HTTP 请求的类 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 将 cookie 设置为在当天结束时过期

    我想设置一个 cookie 并让它在一天结束时过期 这有效 但 24 小时后过期 setcookie route upgrade voted true time 86400 这不起作用 setcookie route upgrade vot
  • 使用 PHP glob 列出 FTP 服务器上的文件不起作用

    我使用此代码来访问目录 location files pictures glob location png 我想使用 FTP 访问远程路径 location opendir ftp user password host name files
  • 使用 XPATH(和 PHP)从样式属性中选择背景 url

    我只想从此背景图像样式属性中选择 url 这可以通过 XPATH 实现吗 a href http www test com style background image none test a 我有类似的东西 url xpath gt qu
  • 在 PHP 字符串中格式化 MySQL 代码

    是否有任何程序 IDE 可以在 PHP 字符串中格式化 MySQL 代码 例如 我使用 PHPStorm IDE 但它无法做到这一点 它对 PHP 和 MYSQL 执行此操作 但不适用于 php 字符串内的 MYSQL 我已准备好使用新的
  • 如何在 Windows 上安装 Zend 框架

    安装 Zend Framework 就是这么简单 是的 对 好吧 我正在写一本初学者的书 有一件不太详细的事情是最重要的部分 安装该死的东西 浏览了几个小时的快速入门指南后 它只说 下载 Zend 添加包含目录 bla bla 然后就完成了
  • 使用PHP从doc、xls文件中读取数据

    我想知道是否可以从 doc 和 xls 文件中读取数据并将 将内容读取到图像文件中 创建文档的页面样本 例如 我有一些文件希望我的客户购买 所以我需要自动创建小图像 例如我的文档样本 我们将不胜感激您的帮助 对于读取 xls 文件 我真的推
  • PHP 中的 -> 和 :: 有什么区别?

    这个东西困扰我好久了 一直找不到 在 php 中使用 和 gt 之间的类有什么区别 让我举个例子 想象一个名为 MyClass 的类 该类中有一个函数 myFunction 使用有什么区别 MyClass myclass new MyCla
  • 雄辩的第一个 where 子句

    我想知道 Laravel 如何实现雄辩的语法 以便可以静态调用第一个 where 子句User where User where id 23 gt where email email gt first 他们有吗public static f
  • PHP 表单 - 带验证蜜罐

    我有以下内容 效果很好 但对垃圾邮件机器人开放 我想放入蜜罐 而不是验证码 下面的代码适用于验证姓名 电子邮件 消息 但我无法让它与蜜罐一起工作 任何人都可以查看 蜜罐 代码并告诉我如何修复它吗 我希望表单给出 success2 不允许垃圾
  • 在本地 SDK 服务器上工作时,实时 Google App Engine 上出现 404

    我已经在GAE标准环境上部署了几个PHP应用程序 一切正常 现在我正在部署一个新应用程序 该应用程序位于由gcloudSDK按预期工作 终端命令 dev appserver py log level warning app yaml 问题是
  • Laravel 搜索关系

    我有两个相关的模型 我正在尝试在产品中进行搜索 并且仅显示实际搜索结果 而不是找到该产品的类别的所有产品 我不想搜索任何类别 因为无论搜索什么或找到什么 类别都会始终显示 Example I have the following categ
  • PayPal 网关已拒绝请求。安全标头无效(#10002:安全错误 Magento

    在 magento 中增加 PayPal 预付款 我已填写 magento admin 中的所有凭据 但是当我进入前端并单击 pay pal 按钮时 它给出了 PayPal 网关已拒绝请求 安全标头无效 10002 安全错误 我用谷歌搜索了
  • 如何从日期中查找该月的最后一天?

    如何在 PHP 中获取该月的最后一天 Given a date 2009 11 23 我要2009 11 30 并给出 a date 2009 12 23 我要2009年12月31日 t返回给定日期所在月份的天数 请参阅的文档date ht

随机推荐