excelwebzone/recaptcha-bundle

此插件提供简单的reCAPTCHA表单字段集成

安装数: 6,371,621

依赖: 21

建议者: 4

安全性: 0

星级: 396

关注者: 10

分支: 160

开放问题: 74

类型:symfony-bundle

v1.5.40 2024-01-09 14:23 UTC

README

Actions Status

此插件为Symfony提供简单的reCAPTCHA表单字段

安装

步骤 1: 使用Composer并启用Bundle

要在您的终端中安装EWZRecaptchaBundle,只需输入Composer命令

php composer.phar require excelwebzone/recaptcha-bundle

现在,Composer将自动下载所有必需的文件,并为您安装它们。您需要做的只是更新您的AppKernel.php文件,并注册新的Bundle

<?php

// in AppKernel::registerBundles()
$bundles = array(
    // ...
    new EWZ\Bundle\RecaptchaBundle\EWZRecaptchaBundle(),
    // ...
);

步骤 2: 配置Bundle的

注意:reCAPTCHA系统版本2和版本3的配置选项不同。一些以前的选项在版本3中不起作用。

请将以下内容添加到您的配置文件中

注意:如果您使用symfony 4,配置将在config/packages/ewz_recaptcha.yaml中。本地开发环境有其自己的配置在config/packages/dev/ewz_recaptcha.yaml中。

版本2和版本3的配置

版本设置确定哪些配置选项可用。将版本设置为与您的Google reCAPTCHA设置相对应的版本(有效值:2或3)

# app/config/config.yml

ewz_recaptcha:
    // ...
    version: 2

您可以轻松禁用reCAPTCHA(例如在本地或测试环境中)

# app/config/config.yml

ewz_recaptcha:
    // ...
    enabled: false

在此处输入公钥和私钥

# app/config/config.yml

ewz_recaptcha:
    // ...
    public_key:  here_is_your_public_key
    private_key: here_is_your_private_key

www.google.com在中国大陆被封锁,您可以通过以下方式覆盖默认服务器(有关更多信息,请参阅https://developers.google.com/recaptcha/docs/faq#can-i-use-recaptcha-globally

# app/config/config.yml

ewz_recaptcha:
    // ...
    api_host: recaptcha.net

您可以添加HTTP代理配置

# app/config/config.yml

ewz_recaptcha:
    // ...
    http_proxy:
        host: proxy.mycompany.com
        port: 3128
        auth: proxy_username:proxy_password

版本2仅配置

设置默认语言环境

# app/config/config.yml

ewz_recaptcha:
    // ...
    # Not needed as "%kernel.default_locale%" is the default value for the locale key
    locale_key:  %kernel.default_locale%

注意:此Bundle允许客户端浏览器选择安全的https或非安全的http API。

如果您想使用与请求语言环境相同的reCAPTCHA语言默认值,必须激活解析器(默认不激活)

# app/config/config.yml

ewz_recaptcha:
    // ...
    locale_from_request: true

您可以使用Ajax加载reCAPTCHA

# app/config/config.yml

ewz_recaptcha:
    // ...
    ajax: true

如果您已关闭reCAPTCHA端域名检查,您需要通过启用verify_host选项来检查响应的来源

# app/config/config.yml

ewz_recaptcha:
    // ...
    verify_host: true

注意:如果您使用symfony 5并希望使用PHP文件而不是YAML来配置Bundle,配置如下

// config/packages/ewz_recaptcha.php

<?php declare(strict_types=1);

use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $configurator): void
{
    $configurator->extension('ewz_recaptcha', [
        'public_key' => 'here_is_your_public_key',
        'private_key' => 'here_is_your_private_key',
        'locale_key' => '%kernel.default_locale%'
    ]);
};

版本3仅配置

对于版本3的reCAPTCHA,将显示一个信息徽章。如果您以其他方式通知用户使用reCAPTCHA,可以使用以下选项隐藏它(有关更多信息,请参阅https://developers.google.com/recaptcha/docs/faq#hiding-badge

# app/config/config.yml

ewz_recaptcha:
    // ...
    hide_badge: true

要修改默认阈值分数0.5,设置此选项(有关更多信息,请参阅https://developers.google.com/recaptcha/docs/v3#interpreting_the_score

# app/config/config.yml

ewz_recaptcha:
    // ...
    score_threshold: 0.6

恭喜!您已经准备好了!

基本用法

注意:基本用法在reCAPTCHA系统版本2和版本3之间有所不同。

版本2用法

当创建一个新的表单类时,将以下行添加到创建字段

<?php

use EWZ\Bundle\RecaptchaBundle\Form\Type\EWZRecaptchaType;

public function buildForm(FormBuilder $builder, array $options)
{
    // ...
    $builder->add('recaptcha', EWZRecaptchaType::class);
    // ...
}

注意,在低于2.8版本的Symfony中,通过名称而不是类名引用表单类型,使用

<?php

public function buildForm(FormBuilder $builder, array $options)
{
   // ...
   $builder->add('recaptcha', 'ewz_recaptcha');
   // ...
}

您可以使用"attr > options"选项传递额外的reCAPTCHA选项

<?php

use EWZ\Bundle\RecaptchaBundle\Form\Type\EWZRecaptchaType;

public function buildForm(FormBuilder $builder, array $options)
{
    // ...
    $builder->add('recaptcha', EWZRecaptchaType::class, array(
        'attr' => array(
            'options' => array(
                'theme' => 'light',
                'type'  => 'image',
                'size'  => 'normal',
                'defer' => true,
                'async' => true,
            )
        )
    ));
    // ...
}

支持谷歌的无形标签非常简单

<?php

public function buildForm(FormBuilder $builder, array $options)
{
    // ...
    $builder->add('recaptcha', EWZRecaptchaType::class, array(
        'attr' => array(
            'options' => array(
                'theme' => 'light',
                'type'  => 'image',
                'size' => 'invisible',              // set size to invisible
                'defer' => true,
                'async' => true,
                'callback' => 'onReCaptchaSuccess', // callback will be set by default if not defined (along with JS function that validate the form on success)
                'bind' => 'btn_submit',             // this is the id of the form submit button
                // ...
             )
        )
    ));
    // ...
}

注意:如果您使用预定义的回调,则需要将 recaptcha-form 类添加到您的 <form> 标签中。

如果您需要根据网站语言(多站点语言)配置 captcha 语言,您可以通过 "language" 选项传递语言

<?php

public function buildForm(FormBuilder $builder, array $options)
{
    // ...
    $builder->add('recaptcha', EWZRecaptchaType::class, array(
        'language' => 'en'
        // ...
    ));
    // ...
}

要验证字段,请使用

<?php

use EWZ\Bundle\RecaptchaBundle\Validator\Constraints as Recaptcha;

/**
 * @Recaptcha\IsTrue
 */
public $recaptcha;

另一种方法是将验证约束作为 FormType 的选项传递。这样,您的数据类仅包含有意义的属性。以上面的例子为例,buildForm 方法将如下所示。请注意,如果您设置了 mapped=>false,则注解将不起作用。您还必须设置 constraints

<?php

use EWZ\Bundle\RecaptchaBundle\Form\Type\EWZRecaptchaType;
use EWZ\Bundle\RecaptchaBundle\Validator\Constraints\IsTrue as RecaptchaTrue;

public function buildForm(FormBuilder $builder, array $options)
{
    // ...
    $builder->add('recaptcha', EWZRecaptchaType::class, array(
        'attr'        => array(
            'options' => array(
                'theme' => 'light',
                'type'  => 'image',
                'size'  => 'normal'
            )
        ),
        'mapped'      => false,
        'constraints' => array(
            new RecaptchaTrue()
        )
    ));
    // ...

现在,表单模板资源已通过容器扩展自动注册。然而,您始终可以实现自己的自定义表单小部件。

PHP:

<?php $view['form']->setTheme($form, array('EWZRecaptchaBundle:Form')) ?>

<?php echo $view['form']->widget($form['recaptcha'], array(
    'attr' => array(
        'options' => array(
            'theme' => 'light',
            'type'  => 'image',
            'size'  => 'normal'
        ),
    ),
)) ?>

Twig:

{% form_theme form '@EWZRecaptcha/Form/ewz_recaptcha_widget.html.twig' %}

{{ form_widget(form.recaptcha, { 'attr': {
    'options' : {
        'theme': 'light',
        'type': 'image',
        'size': 'normal'
    },
} }) }}

如果您不使用表单,您仍然可以使用 JavaScript 实现 reCAPTCHA 字段

PHP:

<div id="recaptcha-container"></div>
<script type="text/javascript">
    $(document).ready(function() {
        $.getScript("<?php echo \EWZ\Bundle\RecaptchaBundle\Form\Type\EWZRecaptchaType::RECAPTCHA_API_JS_SERVER ?>", function() {
            Recaptcha.create("<?php echo $form['recaptcha']->get('public_key') ?>", "recaptcha-container", {
                theme: "clean",
            });
        });
    };
</script>

Twig:

<div id="recaptcha-container"></div>
<script type="text/javascript">
    $(document).ready(function() {
        $.getScript("{{ constant('\\EWZ\\Bundle\\RecaptchaBundle\\Form\\Type\\EWZRecaptchaType::RECAPTCHA_API_JS_SERVER') }}", function() {
            Recaptcha.create("{{ form.recaptcha.get('public_key') }}", "recaptcha-container", {
                theme: "clean"
            });
        });
    });
</script>

自定义

如果您想使用自定义主题,请在设置主题之前放置您的代码块

 <div id="recaptcha_widget">
   <div id="recaptcha_image"></div>
   <div class="recaptcha_only_if_incorrect_sol" style="color:red">Incorrect please try again</div>

   <span class="recaptcha_only_if_image">Enter the words above:</span>
   <span class="recaptcha_only_if_audio">Enter the numbers you hear:</span>

   <input type="text" id="recaptcha_response_field" name="recaptcha_response_field" />

   <div><a href="javascript:Recaptcha.reload()">Get another CAPTCHA</a></div>
   <div class="recaptcha_only_if_image"><a href="javascript:Recaptcha.switch_type('audio')">Get an audio CAPTCHA</a></div>
   <div class="recaptcha_only_if_audio"><a href="javascript:Recaptcha.switch_type('image')">Get an image CAPTCHA</a></div>

   <div><a href="javascript:Recaptcha.showhelp()">Help</a></div>
 </div>

{% form_theme form '@EWZRecaptcha/Form/ewz_recaptcha_widget.html.twig' %}

{{ form_widget(form.recaptcha, { 'attr': {
    'options' : {
        'theme' : 'custom',
    },
} }) }}

v3 使用方法

当创建一个新的表单类时,将以下行添加到创建字段

<?php

use EWZ\Bundle\RecaptchaBundle\Form\Type\EWZRecaptchaV3Type;

public function buildForm(FormBuilder $builder, array $options)
{
    // ...
    $builder->add('recaptcha', EWZRecaptchaV3Type::class);
    // ...
}

您可以使用 "action_name" 选项传递 reCAPTCHA 的动作(有关更多信息,请参阅 https://developers.google.com/recaptcha/docs/v3#actions):

<?php

use EWZ\Bundle\RecaptchaBundle\Form\Type\EWZRecaptchaType;

public function buildForm(FormBuilder $builder, array $options)
{
    // ...
    $builder->add('recaptcha', EWZRecaptchaType::class, array(
        'action_name' => 'contact'
    ));
    // ...
}

要验证字段,请使用

<?php

use EWZ\Bundle\RecaptchaBundle\Validator\Constraints as Recaptcha;

/**
 * @Recaptcha\IsTrueV3
 */
public $recaptcha;

另一种方法是将验证约束作为 FormType 的选项传递。这样,您的数据类仅包含有意义的属性。以上面的例子为例,buildForm 方法将如下所示。您还必须设置 constraints

<?php

use EWZ\Bundle\RecaptchaBundle\Form\Type\EWZRecaptchaV3Type;
use EWZ\Bundle\RecaptchaBundle\Validator\Constraints\IsTrueV3;

public function buildForm(FormBuilder $builder, array $options)
{
    // ...
    $builder->add('recaptcha', EWZRecaptchaV3Type::class, array(
        'action_name' => 'contact',
        'constraints' => array(
            new IsTrueV3()
        )
    ));
    // ...

高级使用

可以注册 reCAPTCHA 表单服务。为此,按如下方式输入服务定义(在此示例中我们在 PHP 中这样做)

<?php

$ewzRecaptchaConfiguration = array();
$ewzRecaptchaConfiguration['enabled'] = isset($_ENV['RECAPTCHA_PUBLIC'], $_ENV['RECAPTCHA_PRIVATE']);
$ewzRecaptchaConfiguration['public_key'] = $_ENV['RECAPTCHA_PUBLIC'] ?? null;
$ewzRecaptchaConfiguration['private_key'] = $_ENV['RECAPTCHA_PRIVATE'] ?? null;
$ewzRecaptchaConfiguration['api_host'] = 'recaptcha.net';
$ewzRecaptchaConfiguration['version'] = 3;

$ewzRecaptchaConfiguration['service_definition'] = array();
$ewzRecaptchaConfiguration['service_definition'][] = [
    'service_name' => 'ContactRecaptchaService',
    'options' => [
        'action_name' => 'form'
    ]
];

// Add more form services here

// ...
$container->loadFromExtension('ewz_recaptcha', $ewzRecaptchaConfiguration);
// ...

现在,服务可以通过 ewz_recaptcha.[service_name] 访问。它们可以注册到您的表单类型类

<?php

namespace MyNamespace\DependencyInjection;

use MyNamespace\Form\ContactType;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Extension\Extension;

class ContactFormExtension extends Extension
{

    public function load(array $configs, ContainerBuilder $container)
    {
        $container->register(ContactType::class)
            ->addArgument(new Reference('ewz_recaptcha.ContactRecaptchaService'))
            ->addTag('form.type');
    }
}
// ...

表单类型类本身以此方式使用注入的服务

<?php

namespace MyNamespace\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;

class ContactType extends AbstractType
{
    /** @var FormBuilderInterface */
    private $recaptcha;

    public function __construct(?FormBuilderInterface $recaptcha)
    {
        $this->recaptcha = $recaptcha;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // ...
        if(null !== $this->recaptcha) {
            $builder->add($this->recaptcha);
        }
        // ...
    }