superrb/google-recaptcha

Symfony 4 Google Recaptcha 集成

1.1.1 2022-11-17 14:37 UTC

This package is auto-updated.

Last update: 2024-09-17 18:38:15 UTC


README

Google Recaptcha v3 Symfony 4 包

安装

composer require superrb/google-recaptcha

创建以下环境变量

###> superrb/google-recaptcha ###
SUPERRB_GOOGLE_RECAPTCHA_SITE_KEY="Get From https://www.google.com/recaptcha/intro/v3.html"
SUPERRB_GOOGLE_RECAPTCHA_SECRET_KEY="Get From https://www.google.com/recaptcha/intro/v3.html"
###< superrb/google-recaptcha ###

将验证器添加到您的表单中,这将创建一个隐藏字段,我们必须将返回的令牌放入其中以允许服务器端验证。

use Superrb\GoogleRecaptchaBundle\Validator\Constraint\GoogleRecaptcha;

// ...

public function buildForm(FormBuilderInterface $builder, array $options)
{
    // ...
    $builder->add('recaptcha', HiddenType::class, [
        'attr' => [
            'class' => 'superrb-google-recaptcha',
        ],
        'constraints' => [
            new GoogleRecaptcha(),
        ],
    ]);
}

类很重要,因为它在标准集成中使用来识别前端字段。如果您正在创建自己的前端集成,则可以以自己的方式识别字段。

前端集成

标准集成

您可以使用以下 Twig 函数输出标准前端集成。这将自动生成令牌并将其添加到隐藏字段中。这是一种最简单的集成,但它也有一些注意事项

  • 如果表单出错,令牌将无效且无法再次使用。您可以在控制器中清空字段以错误处理,然后它将被重新填充。
  • 令牌将在 2 分钟后过期。如果您的表单很长,它可能会在表单提交之前过期,导致用户验证失败。
{{ google_recaptcha_standard_integration() | raw }}
{{ form_start(form) }}
{{ form_end(form) }}

JavaScript(与 Turbolinks 兼容)

为网站密钥创建一个常量并创建一个容器来保存配置。这应该放在您的布局中,以便在使用 Turbolinks 时始终可用,如果您不使用 Turbolinks,则只需要在包含受保护表单的页面上。

<script>const RECAPTCHA_KEY = '{{ google_recaptcha_site_key() }}';</script>
<div id="recaptcha-container" data-turbolinks-permanent></div>

使用此 JavaScript 组件并根据您的需求进行自定义

import LiveNodeList from 'live-node-list'
import {bind} from 'decko'
import { load as loadRecaptcha } from 'recaptcha-v3'

export default class GoogleRecaptcha {
  forms = new LiveNodeList('form.form--contact')

  constructor () {
    this.registerListeners()
  }

  @bind
  handleSubmit (e) {
    const recaptchaInput = document.querySelector('input.superrb-google-recaptcha')
    if (recaptchaInput && !recaptchaInput.value) {
      e.preventDefault()
      e.stopPropagation()
      return this.setupRecaptcha(e)
    }

    return true
  }

  @bind
  async setupRecaptcha(e) {
    const recaptchaInput = document.querySelector('input.superrb-google-recaptcha')
    if (recaptchaInput) {
      // Load recaptcha library
      if (!window.recaptcha) {
        window.recaptcha = await loadRecaptcha('explicit', {autoHideBadge: true})
        this.recaptchaHandle = grecaptcha.render('recaptcha-container', {
          'sitekey': RECAPTCHA_KEY,
          'badge': 'inline', // must be inline
          'size': 'invisible' // must be invisible

        })
      }

      // Get a recaptcha token
      const token = await window.grecaptcha.execute(this.recaptchaHandle)

      // Append the recaptcha token to the form
      recaptchaInput.value = token

      const form = e.currentTarget || e.target
      form.submit()
    }
  }

  @bind
  registerListeners() {
    const recaptchaInput = document.querySelector('input.superrb-google-recaptcha')
    if(recaptchaInput) {
      recaptchaInput.value = null
    }

    this.forms.addEventListener('submit', this.handleSubmit)
  }
}

使用 jQuery 的 Ajax 表单

加载库并创建一个全局常量用于网站密钥

{{ google_recaptcha_output_src() | raw }}
<script>const RECAPTCHA_KEY = '{{ google_recaptcha_site_key() }}';</script>

将 jQuery 事件绑定到表单提交,以生成令牌并将其插入隐藏字段

$('form').unbind('submit').submit(function(e){
    e.preventDefault();
    var form = $(this);

    // get the token
    grecaptcha.ready(function() {
        grecaptcha.execute(RECAPTCHA_KEY, {action: 'homepage'}).then(function (token) {
            // add the token to the hidden field
            $('input.superrb-google-recaptcha').val(token);
            
            // Process and submit form
        });
    });
});

问题和故障排除

所有问题: tech@superrb.com