纯HTML/PHP的Kirby站点无登录集成Recaptcha实现Firebase表单提交
实现思路与步骤
前期准备
- 前往Google reCAPTCHA管理后台申请v2验证码(可见复选框或隐形模式都可以),获取两个密钥:
- 站点密钥(Site Key):可公开放在前端代码中
- 服务端密钥(Secret Key):只能存在服务端PHP代码中,绝对不能暴露到前端
- 关闭Firebase数据库的公共写入权限,调整安全规则为仅管理员账号可写入,避免前端配置泄露导致恶意写入
- 在Kirby CMS项目中安装Firebase Admin PHP SDK,用于服务端写入Firebase数据库
1 修改前端HTML代码
在原有表单中加入reCAPTCHA容器,并引入官方JS资源:
<!-- 头部引入reCAPTCHA JS --> <script src="https://www.google.com/recaptcha/api.js" async defer></script> <form id="add-item" action="?" method="POST"> <label for="f-name">Submitted by:</label> <input type="text" id="f-name" name="f-name" placeholder="your name" required> <!-- 新增reCAPTCHA容器,替换成你自己的站点密钥 --> <div class="g-recaptcha" data-sitekey="你申请的站点密钥"></div> <button type="submit">Submit</button> </form>
2 修改前端提交逻辑
原有直接前端写入Firebase的逻辑存在安全风险,改为先提交到PHP后端验证reCAPTCHA,验证通过后再由服务端写入数据库:
document.querySelector("#add-item").addEventListener("submit", function(e){ e.preventDefault(); const fName = document.querySelector('#f-name').value.trim(); const recaptchaToken = grecaptcha.getResponse(); // 基础校验 if(!fName) { alert('请填写姓名'); return false; } if(!recaptchaToken) { alert('请完成人机验证'); return false; } // 提交数据到后端验证接口 fetch('/your-php-endpoint', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: `f_name=${encodeURIComponent(fName)}&recaptcha_token=${encodeURIComponent(recaptchaToken)}` }) .then(res => res.json()) .then(data => { if(data.code === 0) { alert('提交成功'); document.querySelector('#add-item').reset(); grecaptcha.reset(); } else { alert(data.msg || '提交失败,请重试'); grecaptcha.reset(); } }) .catch(err => { alert('网络错误,请重试'); grecaptcha.reset(); }) })
3 编写PHP后端验证逻辑
在Kirby中自定义一个路由或者单独创建PHP接口文件,实现reCAPTCHA验证和Firebase写入逻辑:
<?php // 替换成你自己的reCAPTCHA服务端密钥 $secretKey = '你的服务端密钥'; $fName = $_POST['f_name'] ?? ''; $recaptchaToken = $_POST['recaptcha_token'] ?? ''; // 基础参数校验 if(empty($fName) || empty($recaptchaToken)) { echo json_encode(['code' => 1, 'msg' => '参数错误']); exit; } // 向谷歌发起reCAPTCHA验证请求 $verifyResponse = file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret='.$secretKey.'&response='.$recaptchaToken); $responseData = json_decode($verifyResponse); if($responseData->success) { // 验证通过,调用Firebase Admin SDK写入数据 $uid = Date('YmdHis').uniqid(); // 这里替换为你自己的Firebase Admin SDK写入逻辑 $firebase->getReference('tableRef/item-'.$uid)->set([ 'contributor' => $fName ]); echo json_encode(['code' => 0, 'msg' => '提交成功']); } else { echo json_encode(['code' => 2, 'msg' => '人机验证失败,请重试']); } exit; ?>
注意事项
- 必须关闭Firebase数据库的公共写入权限,所有写入操作必须通过服务端完成,避免恶意用户绕过前端逻辑直接写入垃圾数据
- reCAPTCHA服务端密钥严禁泄露到前端代码中
- 若你使用的是隐形reCAPTCHA,只需调整前端reCAPTCHA的渲染逻辑即可,服务端验证逻辑无需修改
内容的提问来源于stack exchange,提问作者christopher
相关产品推荐
相关产品推荐

