saeven/zf2-circlical-recaptcha

ZF2 模块,让您轻松集成谷歌新的、更简单的 recaptcha(减少愤怒的老年人总是好事!)

1.3 2022-01-31 14:41 UTC

This package is auto-updated.

Last update: 2024-09-21 22:52:03 UTC


README

Total Downloads Codacy Badge Codacy Badge Build Status

谷歌刚刚推出了他们优秀的全新 CAPTCHA(减少愤怒的老年人总是好事!),您想将其集成到您的 ZF2/ZF3 项目中!请用户和管理员一样,通过这个简单的模块来使用。

Captcha Image

需求

将此行添加到您的 composer.json 中

"saeven/zf2-circlical-recaptcha": "dev-master"

然后,在您的应用程序的 module.config.php 中包含 'CirclicalRecaptcha',。模块现在应该被加载。

配置

circlical.recaptcha.local.php 复制到您的 config/autoload 文件夹中。打开它,并插入您的 ReCaptcha 密钥 - 您可以从 谷歌网站 获取这些密钥。

<?php
return [
    'circlical' => [
        'recaptcha' => [
            'client' => 'yourclientkeygoeshere',
            'server' => 'yourserverkeygoeshere',
            'bypass' => false,
            'default_timeout' => 900,
        ],
    ],
];

第三个参数是为了帮助您通过功能测试(例如,behat)。您可以根据某些固定的环境变量设置 'bypass' 为 true(不验证 captcha),例如

'bypass' => getenv('SOMEKEY') === 'development'

第四个是您允许的 captcha 提供和解决之间的超时时间(以秒为单位)。

模板

您需要将 captcha 添加到您的表单模板中,例如,使用 Twig 它看起来像这样

<div class="form-group" style="margin-bottom:25px;margin-top:25px;">
    {{ formLabel( form.get('g-recaptcha-response') ) }}
    {{ recaptcha( form.get('g-recaptcha-response') ) }}
    <div class="error_container alert alert-danger">{{ formElementErrors( form.get('g-recaptcha-response') ) }}</div>
</div>

目前,g-recaptcha-response 是不可变的。原因在于谷歌使用此名称渲染它,没有选项可以更改

表单 & 输入过滤器

如果您不熟悉 ZF2,这里有一些示例表单代码,它实现了 captcha。需要的比这多,但您可以看到元素是如何添加的,以及相应的输入过滤器(验证器)也是如何添加的。

<?php

namespace CirclicalUser\Form;

use Laminas\Form\Element,
    Laminas\Captcha,
    Laminas\InputFilter,
    Laminas\Form\Element\Password,
    Laminas\Form\Element\Text,
    Laminas\Form\Form,
    CirclicalUser\Form\Element\Recaptcha,
    Laminas\Form\Element\Button;


class UserForm extends Form
{

    const       EMAIL = 'email';

    public function __construct( $name, $options = array() )
    {
        parent::__construct( $name, $options );
    }

    /**
     * Construct a registration form, with an AuthenticationFormInterface instance to establish minimum field count
     */
    public function init()
    {

          $this->add([
              'name'    => 'g-recaptcha-response',
              'type'    => Recaptcha::class,
              'options' => [
                  'label'     => _( "Please complete the challenge below" ),
                  'no_sitekey' => false,
                  'no_script' => false,
                  'language' => 'en', // see https://developers.google.com/recaptcha/docs/language
              ],
          ]);


        $this->add([
            'name'      => self::EMAIL,
            'type'      => self::EMAIL,
            'options' => [
                'label' => _( 'Email' ),
            ],
            'attributes' => [
                'maxlength' => 254,
            ],
        ]);

        $this->add([
            'name' => 'email_confirm',
            'type' => self::EMAIL,
            'options' => [
                'label' => _( "Confirm Email" ),
            ],
            'attributes' => [
                'maxlength' => 254,
            ],
        ]);


        $this->add([
            'name' => 'submit',
            'type' => Button::class,
            'options' => [
                'label' => _( "Submit" ),
            ],
            'attributes' => [
                'class' => 'btn btn-primary',
                'type'  => 'submit',
            ]
        ]);
    }
}

以下是一个示例 InputFilter

<?php

namespace CirclicalUser\InputFilter;

use CirclicalUser\Form\Validator\RecaptchaValidator;
use Doctrine\Common\Persistence\ObjectRepository;
use DoctrineModule\Validator\NoObjectExists;
use Laminas\Filter\StringToLower;
use Laminas\Filter\StringTrim;
use Laminas\InputFilter\InputFilter;
use Laminas\Form\Element;
use Laminas\Captcha;
use CirclicalUser\Form\Filter\ArrayBlock;
use HTMLPurifier;
use Laminas\Validator\EmailAddress;
use Laminas\Validator\StringLength;

class UserInputFilter extends InputFilter implements UserInputFilterInterface
{
    const EMAIL     = 'email';
    const RECAPTCHA = 'g-recaptcha-response';

    protected $userRepository;
    protected $has_captcha;


    public function __construct( ObjectRepository $userRepository, $has_captcha )
    {
        $this->userRepository = $userRepository;
        $this->has_captcha    = $has_captcha;
    }

    public function init()
    {

        if( $this->has_captcha )
        {
            $this->add([
                'name' => self::RECAPTCHA,
                'required' => true,
                'messages' => [_("Please complete the anti-robot check!")],
                'validators' => [
                    ['name' => \CirclicalRecaptcha\Form\Validator\RecaptchaValidator::class,],
                ],
            ]);

            $this->get( self::RECAPTCHA )->setBreakOnFailure( true );
        }

        $this->add([
            'name' => 'email',
            'required' => true,
            'filters' => [
                ['name' => ArrayBlock::class],
                ['name' => StringTrim::class],
                ['name' => HTMLPurifier::class],
                ['name' => StringToLower::class],
            ],
            'validators' => [
                [
                    'name' => EmailAddress::class,
                    'options' => [
                        'useMxCheck'        => true,
                        'useDeepMxCheck'    => true,
                        'useDomainCheck'    => true,
                        'message'           => _( "That email address has a typo in it, or its domain can't be checked" ),
                    ],
                ],

                [
                    'name' => NoObjectExists::class,
                    'options' => [
                        'fields'            => ['email'],
                        'messages'          => [
                            NoObjectExists::ERROR_OBJECT_FOUND => _( "That email is already taken, please log in instead" ),
                        ],
                        'object_repository' => $this->userRepository,
                    ],
                ],
            ],
        ]);

        $this->add([
            'name' => 'email_confirm',
            'required' => true,
            'filters' => [
                ['name' => ArrayBlock::class],
                ['name' => StringTrim::class],
                ['name' => HTMLPurifier::class],
                ['name' => StringToLower::class],
            ],
            'validators' => [
                [
                    'name' => 'identical',
                    'options' => [
                        'message' => _( "Your email and confirmation email are different" ),
                        'token' => self::EMAIL,
                    ],
                ],
            ],
        ]);
    }
}

这就完成了!注意表单初始化中可选的 no_sitekeyno_script 选项。如果您在同一视图中放置了多个 recaptcha,但需要动态地淡入和淡出它们,这些选项将很有用。