如何排查PHP联系表单的Google reCAPTCHA验证失败问题?
PHP联系表单Google reCAPTCHA后端验证失败修复方案
原代码核心问题
- 未处理
file_get_contents请求Google验证服务器失败的场景(如网络超时、DNS解析错误),此时$recaptcha_json会为null,直接访问->success会触发致命错误,导致验证逻辑完全跳过。 - 未校验
g-recaptcha-response字段是否存在,恶意请求可绕过前端验证提交空值,后端直接发送空响应给Google,若请求失败无错误处理,会引发逻辑异常。 - 邮件内容变量映射错误:原代码中
$message = $_POST['subject'];,通常表单消息内容字段应为message,此处会导致邮件内容错误。
修复后完整代码
<?php if ($_SERVER['REQUEST_METHOD'] == 'POST') { // 替换为你的reCAPTCHA密钥 $recaptcha_secret = "你的真实密钥"; // 先校验reCAPTCHA响应是否存在 if (!isset($_POST['g-recaptcha-response']) || empty($_POST['g-recaptcha-response'])) { echo "<script>alert('请完成reCAPTCHA验证后提交表单。');</script>"; exit; } $recaptcha_response = $_POST['g-recaptcha-response']; $recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify'; $recaptcha_data = array( 'secret' => $recaptcha_secret, 'response' => $recaptcha_response, 'remoteip' => $_SERVER['REMOTE_ADDR'] // 可选:添加用户IP,提升验证准确性 ); $recaptcha_options = array( 'http' => array ( 'method' => 'POST', 'content' => http_build_query($recaptcha_data), 'header' => 'Content-Type: application/x-www-form-urlencoded' // 明确请求头格式 ) ); $recaptcha_context = stream_context_create($recaptcha_options); $recaptcha_result = file_get_contents($recaptcha_url, false, $recaptcha_context); // 处理请求失败的情况 if ($recaptcha_result === false) { echo "<script>alert('验证服务暂时不可用,请稍后重试。');</script>"; exit; } $recaptcha_json = json_decode($recaptcha_result); // 校验JSON解析是否成功,以及验证是否通过 if ($recaptcha_json && $recaptcha_json->success === true) { // 校验表单必填字段 if (isset($_POST['fullName'], $_POST['email'], $_POST['message'])) { $fullName = trim($_POST['fullName']); $email = trim($_POST['email']); $message = trim($_POST['message']); // 额外校验邮箱格式 if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { echo "<script>alert('请输入有效的邮箱地址。');</script>"; exit; } $to = "你的接收邮箱地址"; $subject = "联系表单提交来自: $fullName"; // 使用PHP_EOL适配不同系统换行格式 $headers = "From: $email" . PHP_EOL . "Reply-To: $email" . PHP_EOL . "X-Mailer: PHP/" . phpversion(); if (mail($to, $subject, $message, $headers)) { echo "<script>alert('感谢你的留言!消息已发送。');</script>"; } else { echo "<script>alert('发送失败,请稍后重试或刷新页面。');</script>"; } } else { echo "<script>alert('请填写完整的表单信息。');</script>"; } } else { // 调试时可取消注释查看具体错误码 // $errors = $recaptcha_json->error_codes ?? []; echo "<script>alert('reCAPTCHA验证失败,请重新验证。');</script>"; } } ?>
关键改动说明
- 前置字段检查:先判断
g-recaptcha-response是否为空,直接拦截未验证的请求。 - 请求失败处理:当
file_get_contents返回false时,给出友好提示并终止流程,避免致命错误。 - 添加用户IP:向Google验证接口提交用户IP,提升验证安全性与准确性。
- 明确请求头:设置
Content-Type确保请求格式正确,避免接口解析失败。 - 修复变量映射:将
$_POST['subject']改为$_POST['message'](需与前端表单字段名对应)。 - 邮箱格式校验:避免无效邮箱导致邮件发送失败。
- 系统兼容换行:使用
PHP_EOL替代硬编码换行符,适配不同操作系统的邮件格式要求。
内容的提问来源于stack exchange,提问作者RobH
相关产品推荐
相关产品推荐

