You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 5.8自定义Recaptcha验证规则重复调用问题求助

解决Laravel 5.8自定义Recaptcha验证规则被重复调用的问题

我之前也碰到过类似的情况,结合你的描述和Laravel 5.8的验证机制,大概率是以下几个原因导致验证规则被调用两次,进而触发Google Recaptcha的timeout-or-duplicate错误(毕竟Recaptcha token只能被校验一次):

1. 表单请求的prepareForValidation()触发二次验证

如果你的RegistrationRequest类重写了prepareForValidation()方法,并且在这个方法里修改了请求数据(比如合并参数、格式化字段),Laravel会自动重新触发验证流程,导致你的自定义Recaptcha规则被执行两次。

举个例子,假设你的请求类里有这段代码:

protected function prepareForValidation()
{
    $this->merge([
        'email' => strtolower($this->input('email')),
        'username' => trim($this->input('username')),
    ]);
}

修改请求参数后,Laravel会重新运行整个验证逻辑,同一个Recaptcha token被提交给Google校验两次,第二次自然就返回timeout-or-duplicate了。

2. 重复的验证逻辑调用

检查你的路由和控制器代码,是否存在双重验证的情况:

  • 路由被ValidationMiddleware中间件包裹,同时控制器方法又注入了RegistrationRequest表单请求;
  • 控制器方法中手动调用了$request->validate()或者$this->validate(),同时方法参数使用了表单请求类。

这两种情况都会触发两次验证流程,导致token被重复校验。

3. Laravel 5.8表单验证的内部机制问题

你提到的官方issue #25736确实涉及验证规则重复执行的场景,比如使用条件验证(如sometimes)或者规则依赖时,可能会触发重复验证。不过你的场景是required+自定义Rule,大概率还是前面两种情况,但也可以排查下自定义Rule中是否存在修改请求数据的逻辑,间接触发了二次验证。

快速解决方法

既然控制器静态方法校验可以正常工作,说明单次校验没问题。如果想继续使用表单请求的方式,可以在自定义Rule中加入缓存逻辑,避免重复请求Google接口:

use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;

public function passes($attribute, $value)
{
    // 用token作为缓存键,避免重复校验同一个token
    $cacheKey = 'recaptcha_validation_' . $value;
    
    if (Cache::has($cacheKey)) {
        return Cache::get($cacheKey);
    }

    // 调用Google Recaptcha接口校验
    $response = Http::post('https://www.google.com/recaptcha/api/siteverify', [
        'secret' => config('services.recaptcha.secret'),
        'response' => $value,
        'remoteip' => request()->ip(),
    ]);

    $validationResult = $response->json();
    $isValid = $validationResult['success'] ?? false;

    // 缓存校验结果5分钟(根据Recaptcha token有效期调整)
    Cache::put($cacheKey, $isValid, 5);

    Log::info('Recaptcha校验日志', ['success' => $isValid]);
    return $isValid;
}

这样即使验证规则被调用两次,第二次会直接读取缓存的结果,不会重复请求Google接口,也就不会出现timeout-or-duplicate错误。

另外,建议先排查RegistrationRequest的prepareForValidation()方法和路由/控制器的验证逻辑,找到触发二次验证的根源,从根本上解决问题。

内容的提问来源于stack exchange,提问作者Marshall

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:26:51