zanysoft/laravel-recaptcha

为 Laravel 提供的高级 Google reCAPTCHA 包

1.0.1 2023-06-02 12:38 UTC

This package is auto-updated.

Last update: 2024-09-05 07:33:05 UTC


README

为 Laravel 提供的高级且易于使用的 Google reCAPTCHA 包

可用的 reCAPTCHA 版本

  • v2 无痕
  • v2 复选框
  • v3

系统要求

Composer

您可以通过 composer 安装此包

$ composer require zanysoft/laravel-recaptcha

Laravel 6.0 或更高版本使用包自动发现,因此不需要您手动添加 Service Provider,但如果您不使用自动发现,则 ReCaptchaServiceProvider 必须在 config/app.php 中注册

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

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

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

配置

使用以下 artisan 命令发布包创建 config/recaptcha.php 配置文件

$ php artisan vendor:publish --provider="ZanySoft\ReCaptcha\ReCaptchaServiceProvider" 设置环境 添加您的 API 密钥 打开 .env 文件并设置 RECAPTCHA_SITE_KEYRECAPTCHA_SECRET_KEY

在您的 .env 文件中

RECAPTCHA_SITE_KEY=YOUR_API_SITE_KEY
RECAPTCHA_SECRET_KEY=YOUR_API_SECRET_KEY

完整配置 打开 config/recaptcha.php 配置文件并设置版本

return [
    'site_key' => env('RECAPTCHA_SITE_KEY', ''),
    'secret_key' => env('RECAPTCHA_SECRET_KEY', ''),
    'version' => 'v2', // supported: v3|v2|invisible
    'skip_ip' => [], // array of IP addresses - String: dotted quad format e.g.: 127.0.0.1
    'validation_route' => env('RECAPTCHA_VALIDATION_ROUTE', 'laravel-recaptcha/validate'),
    'token_parameter_name' => env('RECAPTCHA_TOKEN_PARAMETER_NAME', 'token')
];

site_keysecret_key 是您必须创建以执行 Google API 认证的 reCAPTCHA 密钥。有关网站密钥和密钥的更多信息,请访问 Google reCAPTCHA 开发者文档

version 表示 reCAPTCHA 版本(支持:v3|v2|invisible)。有关 reCAPTCHA 版本的更多信息,请参阅 https://developers.google.com/recaptcha/docs/versions

skip_ip 是白名单 IP 地址列表,如果识别到,则禁用 reCAPTCHA 验证(始终返回 true)并且如果您在 blade(视图)文件中嵌入 JS 代码,则不会执行任何验证调用。

validation_route 是通过内置的 JavaScript 验证脚本来调用的路由(仅限 v3)

token_parameter_name 是发送到 validation_route 的 "token" GET 参数的名称以进行验证(仅限 v3)

重新加载配置缓存文件!!!重要!!!每次更改某些配置时,请运行以下 shell 命令

$ php artisan config:cache

您已更新?如果您是从旧版本迁移,请将 skip_ip 数组添加到 recaptcha.php 配置文件中。

自定义错误消息 仅适用于 v2无痕 用户。

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

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

如何使用 v2

嵌入到 Blade 中

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

您也可以使用 ReCaptcha::recaptchaApiJsScriptTag($formId)$formId 仅在您使用 ReCAPTCHA 无痕 时是必需的

<!DOCTYPE html>
<html>
    <head>
        ...
        {!! recaptchaApiJsScriptTag(/* $formId - INVISIBLE version only */) !!}
    </head>

ReCAPTCHA v2 复选框

之后,您必须在包含您想要使用字段 g-recaptcha-response 的表单中插入 recaptchaHtmlFormSnippet() 辅助函数。

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

<form>
    ...
    {!! recaptchaHtmlFormSnippet() !!}
    <input type="submit">
</form>

ReCAPTCHA v2 无痕

之后,您必须在包含您想要使用 reCAPTCHA 的表单中插入 recaptchaHtmlFormButton($buttonInnerHTML) 辅助函数。

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

您也可以使用 ReCaptcha::htmlFormButton($buttonInnerHTML)

$buttonInnerHTML 是您想要写在提交按钮上的内容

<form id="{{ formId }}">
    ...
    {!! recaptchaHtmlFormButton(/* $buttonInnerHTML - Optional */) !!}
</form>

**重要!!!** 使用与之前在 recaptchaApiJsScriptTag 函数中设置的相同的 $formId

验证提交数据

recaptcha 添加到您的规则中

$v = Validator::make(request()->all(), [
    ...
    'g-recaptcha-response' => 'recaptcha',
]);

打印表单错误

$errors = $v->errors();

如何使用 v3

嵌入到 Blade 中

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

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

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

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

键是

内置 JavaScript 验证系统

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

callback_catch 发生的情况相同。在响应错误事件中,将调用 callback_catch,并将错误作为参数传递给该函数。如果没有设置,则不会执行任何操作。

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

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

Fetch 浏览器兼容性

验证 Laravel 路由

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

您还可以通过在 recaptcha.php 配置文件中更改 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.tld",
    "score":0.9,
    "success":true
}
  • 当调用 IP 包含在 "skip_ip" 配置白名单中时的输出
{
    "skip_by_ip":true,
    "score":0.9,
    "success":true
}

如果您使用 recaptchaApiV3JsScriptTag 辅助函数在 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>  
    ...
    {!! recaptchaApiV3JsScriptTag([
        '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>

许可证

在 MIT 许可证下