雪软/laravel-recaptcha

为Laravel框架提供简单易用的Google reCAPTCHA包

v6.0.0 2024-03-16 19:20 UTC

README

Laravel ReCAPTCHA 是一个简单易用的Laravel 5包,用于在您的应用程序中嵌入Google reCAPTCHA。

Build Status Scrutinizer Code Quality Code Coverage Packagist version Downloads MIT License

什么是reCAPTCHA?

谷歌开发者表示:“reCAPTCHA可以帮助您抵御垃圾邮件和其他类型的自动化滥用。以下是添加reCAPTCHA到您的网站或应用程序的方法。”

您可以在Google reCAPTCHA开发者指南中找到更多信息。

reCAPTCHA可用版本

目前有3个版本可供使用(适用于Web应用程序)

首先获取您的密钥!

首先,您需要在这里创建自己的API密钥 这里

按照说明进行操作,在过程结束时,您将找到 网站密钥密钥密钥。请妥善保管它们,您很快就会需要它们!

系统要求

(*) 版本3.6.1已准备好支持Laravel 6

Composer

您可以通过Composer安装此包

$ composer require biscolab/laravel-recaptcha

Laravel 5.5(或更高版本)使用包自动发现,因此不需要您手动添加服务提供者,但如果您不使用自动发现,则必须在 config/app.php 中注册 ReCaptchaServiceProvider

'providers' => [
    ...
    Biscolab\ReCaptcha\ReCaptchaServiceProvider::class,
];

您可以使用外观来缩短代码。将 ReCaptcha 添加到您的别名中

'aliases' => [
    ...
    'ReCaptcha' => Biscolab\ReCaptcha\Facades\ReCaptcha::class,
];

发布包

使用以下Artisan命令创建 config/recaptcha.php 配置文件

$ php artisan vendor:publish --provider="Biscolab\ReCaptcha\ReCaptchaServiceProvider"

设置环境

添加您的API密钥

打开 .env 文件,并设置 RECAPTCHA_SITE_KEYRECAPTCHA_SECRET_KEY

# in your .env file
RECAPTCHA_SITE_KEY=<YOUR_API_SITE_KEY>
RECAPTCHA_SECRET_KEY=<YOUR_API_SECRET_KEY>
RECAPTCHA_SKIP_IP=<YOUR_IP_LIST>

RECAPTCHA_SKIP_IP(自v5.2.0起不再需要,CSV格式)允许您添加IP/CIDR(包含子网掩码)列表。它将是 skip_ip 的值

以下环境变量已被删除! 现在只有敏感信息,如API密钥,可以作为环境变量使用,这意味着您必须在 config/recaptcha.php 中设置配置值

  • RECAPTCHA_DEFAULT_VERSION
  • RECAPTCHA_CURL_TIMEOUT
  • RECAPTCHA_DEFAULT_VALIDATION_ROUTE
  • RECAPTCHA_DEFAULT_TOKEN_PARAMETER_NAME
  • RECAPTCHA_DEFAULT_LANGUAGE

完整的配置

打开 config/recaptcha.php 配置文件并设置 version

return [
    'api_site_key'                  => env('RECAPTCHA_SITE_KEY', ''),
    'api_secret_key'                => env('RECAPTCHA_SECRET_KEY', ''),
    // changed in v4.0.0
    'version'                       => 'v2', // supported: "v3"|"v2"|"invisible"
    // @since v3.4.3 changed in v4.0.0
    'curl_timeout'                  => 10,
    'skip_ip'                       => env('RECAPTCHA_SKIP_IP', []), // array of IP addresses - String: dotted quad format e.g.: "127.0.0.1", IP/CIDR netmask eg. 127.0.0.0/24, also 127.0.0.1 is accepted and /32 assumed
    // @since v3.2.0 changed in v4.0.0
    'default_validation_route'      => 'biscolab-recaptcha/validate',
    // @since v3.2.0 changed in v4.0.0
    'default_token_parameter_name' => 'token',
    // @since v3.6.0 changed in v4.0.0
    'default_language'             => null,
    // @since v4.0.0
    'default_form_id'              => 'biscolab-recaptcha-invisible-form', // Only for "invisible" reCAPTCHA
    // @since v4.0.0
    'explicit'                     => false, // true|false
    // @since v4.3.0
    'api_domain'                   => "www.google.com", // default value is "www.google.com"
    // @since v5.1.0
    'empty_message'                => false,
    // @since v5.1.0
    'error_message_key'            => 'validation.recaptcha',
    // @since v4.0.0
    'tag_attributes'               => [
        'theme'                    => 'light', // "light"|"dark"
        'size'                     => 'normal', // "normal"|"compact"
        'tabindex'                 => 0,
        'callback'                 => null, // DO NOT SET "biscolabOnloadCallback"
        'expired-callback'         => null, // DO NOT SET "biscolabOnloadCallback"
        'error-callback'           => null, // DO NOT SET "biscolabOnloadCallback"
    ]
];

(array) 标签属性

请勿设置 tag_attributes.callbacktag_attributes.expired-callbacktag_attributes.error-callbackbiscolabOnloadCallbackbiscolabOnloadCallback 是当 显式 设置为 true 且widget onload 事件触发时调用的默认JavaScript回调函数。

有关 tag_attributes.* 的更多详细信息,请参阅 https://developers.google.com/recaptcha/docs/display#render_param

重新加载配置缓存文件

!!! 重要!!! 每次更改某些配置时,请运行以下shell命令

$ php artisan config:cache

您已经更新了吗?

如果您是从旧版本迁移过来,请检查您的 config/recaptcha.php 配置文件,并将其与 https://github.com/biscolab/laravel-recaptcha/blob/master/config/recaptcha.php 进行比较。

确保 config/recaptcha.php 已更新

自定义错误信息

仅适用于v2版本和不可见用户。

开始之前,请将验证信息添加到 resources/lang/[LANG]/validation.php 文件。

return [
    ...
    'recaptcha' => 'Hey!!! :attribute is wrong!',
];

嵌入到Blade模板中

在关闭 </head> 标签之前插入 htmlScriptTagJsApi() 辅助函数。

您还可以使用 ReCaptcha::htmlScriptTagJsApi()

<!DOCTYPE html>
<html>
    <head>
        ...
        {!! htmlScriptTagJsApi($configuration) !!}
    </head>

htmlScriptTagJsApi

htmlScriptTagJsApi 函数接受 $configuration 参数。 $configuration 的键取决于您使用的 ReCAPTCHA 类型

ReCAPTCHA v2 复选框

htmlScriptTagJsApi($configuration)

$configuration 参数可以包含以下键

表单设置

在您要使用字段 g-recaptcha-response 的表单中插入 htmlFormSnippet() 辅助函数。

您还可以使用 ReCaptcha::htmlFormSnippet()

<form>
    @csrf

    ...
    {!! htmlFormSnippet() !!}
    <!-- OR -->
    {!! htmlFormSnippet($attributes) !!}
    <input type="submit">
</form>

不要忘记 @csrf blade 指令

htmlFormSnippet([, array $attributes = [] ])

htmlFormSnippet() 函数不需要属性,但您可以覆盖默认的 data- 属性配置

{!! htmlFormSnippet([
    "theme" => "light",
    "size" => "normal",
    "tabindex" => "3",
    "callback" => "callbackFunction",
    "expired-callback" => "expiredCallbackFunction",
    "error-callback" => "errorCallbackFunction",
]) !!}

htmlFormSnippet 方法允许的属性名只有以下几种

  • 主题
  • 大小
  • tabindex
  • 回调
  • 过期回调
  • 错误回调

任何不同的属性名都将被拒绝

自定义

config/recaptcha.php 中,您可以自定义 reCAPTCHA 小部件设置 tag_attributes 数组值。请参阅 完整配置 中的 tag_attributes 部分

ReCAPTCHA v2 不可见

htmlScriptTagJsApi($configuration)

$configuration 参数可以包含以下键

  • form_id 设置 reCAPTCHA 表单 ID。这将覆盖 config/recaptcha.php 中的 default_form_id。此值将由 getFormId() 函数返回,以便设置表单标签的 id 属性。

表单设置

之后,您需要在您要使用 reCAPTCHA 的表单中插入 htmlFormButton($button_label, $properties) 辅助函数。

此函数创建提交按钮,因此您不需要插入 <input type="submit"> 或类似的。

您还可以使用 ReCaptcha::htmlFormButton($button_label, $properties)

$button_label 是您希望在提交按钮上写入的内容

<form id="{{ getFormId() }}">
  @csrf ... {!! htmlFormButton($button_label, $properties) !!}
</form>

不要忘记 @csrf blade 指令

getFormId()

getFormId 函数返回默认表单 ID 值。这是 config/recaptcha.php 中的 default_form_id 或之前设置为 htmlScriptTagJsApi 辅助函数参数的 $configuration['form_id'] 的值。

$configuration['form_id'] 覆盖默认设置。

htmlFormButton()

htmlFormButton 函数接受 2 个参数

  • $button_label: (字符串:可选) 按钮标签。例如:订阅!;
  • $properties: (数组:可选) HTML 按钮属性。例如
// $properties =
[
    'class' => 'btn btn-info',
    'data-foo' => 'bar'
]

如果设置了 data-sitekeydata-callback 属性,它们将被覆盖

如果设置了 class 属性,则附加 g-recaptcha

验证提交数据

recaptcha 添加到您的规则中

$validator = Validator::make(request()->all(), [
    ...
    'g-recaptcha-response' => 'recaptcha',
    // OR since v4.0.0
    recaptchaFieldName() => recaptchaRuleName()
]);

// check if validator fails
if($validator->fails()) {
    ...
    $errors = $validator->errors();
}

嵌入到Blade模板中

在关闭 </head> 标签之前插入 htmlScriptTagJsApi($config) 辅助函数。

<!DOCTYPE html>
<html>
    <head>
        ...
        {!! htmlScriptTagJsApi([
            'action' => 'homepage',
            'callback_then' => 'callbackThen',
            'callback_catch' => 'callbackCatch'
        ]) !!}

        <!-- OR! -->
        
        {!! htmlScriptTagJsApi([
            'action' => 'homepage',
            'custom_validation' => 'myCustomValidation'
        ]) !!}
    </head>

$config 是必需的,它是一个关联数组,包含用于处理 JavaScript 验证的所需配置参数。

键是

内置 JavaScript 验证系统

作为 grecaptcha.execute 的回调,将使用 fetch 函数执行一个 AJAX 调用到 config('recaptcha.default_validation_route')。如果响应成功,将收到一个 Promise 对象,并将其作为参数传递给您设置的 callback_then 函数。如果没有设置,则不会执行任何操作。

callback_catch 的情况相同。在响应错误的情况下,callback_catch 将被调用,错误将作为参数传递到该函数。如果没有设置,则不会执行任何操作。

请访问 Using Fetch 获取有关 fetch JavaScript 函数的更多信息。

警告!!!检查浏览器兼容性 fetch 函数与一些浏览器(如 IE)存在兼容性问题。请创建一个自定义验证函数,并使用其名称设置 custom_validation。该函数必须接受从 Google reCAPTCHA API 收到的 token 作为参数。

Fetch 浏览器兼容性

验证 Laravel 路由

默认验证路由是 config('recaptcha.default_validation_route', 'biscolab-recaptcha/validate')
该包内置了路由和相对控制器。路由经过过滤并由 Laravel web 中间件保护,因此非常重要,您需要嵌入 csrf-token HTML meta 标签并发送 X-Requested-WithX-CSRF-TOKEN 头。

您还可以通过在 recaptcha.php 配置文件中更改 default_validation_route 的值来更改验证端点。

<head>
    ...
    <!-- IMPORTANT!!! remember CSRF token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">
</head>

验证响应对象

输出将是一个包含以下数据的 JSON

  • 默认输出(无错误)
{
    "action":"homepage",
    "challenge_ts":"2019-01-29T00:42:08Z",
    "hostname":"www.yourdomain.ext",
    "score":0.9,
    "success":true
}
  • 当调用 IP 包含在 "skip_ip" 配置白名单中时的输出
{
    "skip_by_ip":true,
    "score":0.9,
    "success":true
}

如果您使用 htmlScriptTagJsApiV3 辅助函数在 blade 文件中嵌入代码,则不会执行任何验证调用!

更多信息请参阅 配置页面

  • 来自 Google reCAPTCHA API 的空响应输出
{
    "error":"cURL response empty",
    "score":0.1,
    "success":false
}

在下一段中,您可以了解如何处理验证 Promise 对象

"callback_then" 和 "callback_catch"

在内置验证之后,您应该执行一些操作。如何做?使用 callback_thencallback_catch 函数。

您需要做的只是创建函数并设置它们的名称作为参数。

  • callback_then 必须接收一个类型为 Promise 的参数。

  • callback_catch 必须接收一个类型为 string 的参数

结果应该类似于以下内容

<head>
    ...
    <!-- IMPORTANT!!! remember CSRF token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">
    ...
    <script type="text/javascript">
        function callbackThen(response){
        	// read HTTP status
            console.log(response.status);
            
            // read Promise object
            response.json().then(function(data){
                console.log(data);
            });
        }
        function callbackCatch(error){
            console.error('Error:', error)
        }   
    </script>    
    ...
    {!! htmlScriptTagJsApiV3([
        'action' => 'homepage',
        'callback_then' => 'callbackThen',
        'callback_catch' => 'callbackCatch'
    ]) !!}    
</head>

"custom_validation" 函数

正如刚才所说的,您可以使用自己的函数来处理验证。为此,您必须编写自己的函数,并将 custom_validation 参数设置为其名称。

结果应该类似于以下内容

<head>
    ...
    <!-- IMPORTANT!!! remember CSRF token --> 
    <meta name="csrf-token" content="{{ csrf_token() }}">
    ...
    <script type="text/javascript">
        function myCustomValidation(token) {
            // do something with token 
        }
    </script>    
    ...
    {!! htmlScriptTagJsApiV3([
        'action' => 'homepage',
        'custom_validation' => 'myCustomValidation'
    ]) !!}    
</head>