bedigit/lara-recaptcha

Laravel 的高级 reCAPTCHA 包

1.1.4 2021-01-26 23:19 UTC

This package is auto-updated.

Last update: 2024-09-27 07:28:11 UTC


README

Laravel 的高级且简便的 Google reCAPTCHA 包

可用的 reCAPTCHA 版本

  • v2 无痕
  • v2 复选框
  • v3

系统要求

Composer

您可以通过 composer 安装此包

$ composer require bedigit/lara-recaptcha:^1.0  

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

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

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

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

配置

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

$ php artisan vendor:publish --provider="Bedigit\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', 'lara-recaptcha/validate'),  
   'token_parameter_name' => env('RECAPTCHA_TOKEN_PARAMETER_NAME', 'token')  
];  

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

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

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

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

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

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

$ php artisan config:cache

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

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

在开始之前,请将验证消息添加到资源文件 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::recaptchaHtmlFormSnippet()

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

ReCAPTCHA v2 无痕

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

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

您也可以使用 ReCaptcha::recaptchaHtmlFormButton($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将在响应错误时被调用,错误将作为参数传递给该函数。如果没有设置,则不会执行任何操作。

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

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

Fetch浏览器兼容性

验证Laravel路由

默认验证路由为config('recaptcha.validation_route', 'lara-recaptcha/validate')
该包内置了路由和相对控制器。路由被过滤并受到Laravel web中间件的保护,这就是为什么在HTML中嵌入csrf-token元标签以及发送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许可证下