Laravel-Inertia中Google reCAPTCHA v3在if语句内校验报错问题
Google reCAPTCHA v3 校验异常:if语句内触发timeout-or-duplicate错误
问题描述
在if语句内校验客户端的Google reCAPTCHA v3分数时,始终返回timeout-or-duplicate错误,但将相同的校验逻辑放在if语句外执行则完全正常。
代码对比
情况1:if语句外校验(执行正常)
public function validate(string $attribute, mixed $value, Closure $fail): void { $endpoint = config('services.google_recaptcha'); $response = Http::asForm()->post($endpoint['url'], [ 'secret' => $endpoint['secret_key'], 'response' => $value, ])->json(); dd('outside of if statement', $response); if(!($response['success'] and ($response['score'] > 0.5))) { $fail('Something went wrong! please try again later.'); } }
执行结果:
"outside of if statement" // app\Rules\Recaptcha.php:25 array:5 [▼ // app\Rules\Recaptcha.php:25 "success" => true "challenge_ts" => "2024-12-26T19:58:05Z" "hostname" => "localhost" "score" => 0.9 "action" => "login" ]
情况2:if语句内校验(触发错误)
public function validate(string $attribute, mixed $value, Closure $fail): void { $endpoint = config('services.google_recaptcha'); $response = Http::asForm()->post($endpoint['url'], [ 'secret' => $endpoint['secret_key'], 'response' => $value, ])->json(); if(!($response['success'] and ($response['score'] > 0.5))) { dd('inside of the if statement', $response); $fail('Something went wrong! please try again later.'); } }
执行结果:
"inside of the if statement" // app\Rules\Recaptcha.php:29 array:2 [▼ // app\Rules\Recaptcha.php:29 "success" => false "error-codes" => array:1 [▼ 0 => "timeout-or-duplicate" ] ]
问题原因及解决方案
原因
timeout-or-duplicate错误表明你正在使用的reCAPTCHA响应令牌已被验证过一次,或者已超时。两种情况的差异源于:
- 情况1中
dd()会直接终止程序,令牌仅被提交到Google验证一次,所以返回成功; - 情况2中,程序会继续执行后续逻辑(或验证规则被重复调用),导致同一个令牌被多次提交验证,Google判定为重复请求,返回错误。
解决方案
- 避免复用令牌:每次测试或用户请求都要生成新的reCAPTCHA响应令牌(刷新页面重新获取),不要重复使用同一个令牌。
- 检查验证逻辑:确认Laravel表单验证中该规则是否被多次调用(比如字段被添加到多个验证场景,或验证逻辑存在重复执行的情况)。
- 优化代码逻辑:确保每个请求中reCAPTCHA令牌只被验证一次,可将验证结果缓存或提前存储,避免重复请求Google接口。
内容的提问来源于stack exchange,提问作者Mohammad Hossein
相关产品推荐
相关产品推荐

