如何通过reCAPTCHA v3验证用户为人类后加载指定HTML内容
问题修复方案
1. 前端response undefined错误修复
该问题由Promise链式调用写法错误导致:你没有将fetch的执行结果返回给下一个.then,导致后续链拿到的参数为undefined,按如下代码修改即可:
function loadContactbubble() { grecaptcha.execute('sitekeyhere', { action: 'onclick' }).then(function (token) { console.log(token); // 需return fetch的执行结果,后续then才能拿到响应对象 return fetch("/load/contactbubble?RecaptchaToken=" + token, { method: "POST", body: token, }) }).then((response) => { console.log(response); if (!response.ok) { const errorBuild = { type: "Error", message: response.message || "Something went wrong", data: response.data || "", code: response.code || "", }; // 此处补充你的错误处理逻辑 return; } // 如需获取返回的HTML内容,调用response.text() return response.text(); }).then(html => { // 此处将拿到的HTML插入到页面对应位置即可 console.log(html); }).catch(err => { // 补充统一异常捕获,避免未处理的Promise报错 console.error('请求出错:', err); }) }
2. reCAPTCHA v3分数校验逻辑位置
必须放在后端实现,前端校验可被篡改,完全没有防护效力。
首先你需要给GResponseModel补充score字段,接收Google返回的校验分数:
[DataContract] public class GResponseModel { [DataMember] public bool success { get; set; } [DataMember] public string challenge_ts { get; set; } [DataMember] public string hostname { get; set; } // 新增score字段接收分数 [DataMember] public decimal score { get; set; } [DataMember(Name = "error-codes")] public string[] error_codes { get; set; } }
之后在ApiController的Post逻辑中补充校验即可:
if (!await _gService.Execute()) { return Ok(_gService.Response.error_codes); } // 补充分数校验,0.5的阈值可根据业务需求调整 if(_gService.Response.score < 0.5m) { return BadRequest("人机验证不通过"); } // 校验通过后再返回邮箱内容 return base.Content("<div>Welcome human! Here is our secret e-mail: test@test.com</div>", "text/html");
3. 安全性问题
你当前的实现不会泄露密钥:reCAPTCHA分为两种密钥,SiteKey本来就是公开参数,需要放到前端供Google服务调用;Secret存储在你后端的appsettings.json中,不会被传输到前端,只要生产环境的配置文件权限配置正确,就不会被窃取。
额外安全建议:校验时可补充判断返回的action是否和前端传的一致,避免验证令牌被冒用。
4. CSP警告处理
生产环境如果不处理CSP警告会导致reCAPTCHA功能失效,你需要在页面头或者后端响应头中补充CSP配置,允许加载Google相关的资源:
如果通过页面meta配置,加在页面head节点内即可:
<meta http-equiv="Content-Security-Policy" content=" script-src 'self' https://www.google.com/recaptcha/ https://www.gstatic.com/recaptcha/; frame-src https://www.google.com/recaptcha/; style-src 'self' 'unsafe-inline'; ">
也可以直接在ASP.NET Core的启动配置中添加全局响应头完成配置。
内容的提问来源于stack exchange,提问作者Munchkin
相关产品推荐
相关产品推荐

