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

ASP.NET 5项目reCaptcha v3在AJAX页面报invalid-input-response错误

问题描述

我正尝试在ASP.NET MVC项目中集成Google reCaptcha v3。该验证在两个页面使用,纯MVC提交的页面运行正常,而用jQuery AJAX提交的页面调用相同验证函数时返回**"invalid-input-response"**错误,但已能从视图获取reCaptcha令牌值。

生成reCaptcha的代码如下
public static IHtmlString ReCaptchaHidden(this HtmlHelper helper)
{
    var mvcHtmlString = new TagBuilder("input")
    {
        Attributes =
       {
            new KeyValuePair<string, string>("type", "hidden"),
            new KeyValuePair<string, string>("id", GoogleReCaptchaVariables.InputName),
            new KeyValuePair<string, string>("name", GoogleReCaptchaVariables.InputName)
       }
    };
    string renderedReCaptchaInput = mvcHtmlString.ToString(TagRenderMode.Normal);
    return MvcHtmlString.Create($"{renderedReCaptchaInput}");
}

public static IHtmlString ReCaptchaJS(this HtmlHelper helper, string useCase)
{
    string reCaptchaSiteKey = GoogleReCaptchaVariables.ReCaptchaSiteKey;
    string reCaptchaApiScript = "<script src='https://www.google.com/recaptcha/api.js?render=" + reCaptchaSiteKey + "'></script>";
    string reCaptchaTokenResponseScript = "<script>$('form').submit(function(e) { e.preventDefault(); grecaptcha.ready(function() { grecaptcha.execute('" + reCaptchaSiteKey + "', {action: '" + useCase + "'}).then(function(token) { $('#" + GoogleReCaptchaVariables.InputName + "').val(token); $('form').unbind('submit').submit(); }); }); }); </script>";
    return MvcHtmlString.Create($"{reCaptchaApiScript}{reCaptchaTokenResponseScript}");
}
验证reCaptcha的代码如下
public string ReCaptchaVerify(string responseToken)
{
    const string apiAddress = "https://www.google.com/recaptcha/api/siteverify";
    string recaptchaSecretKey = GoogleReCaptchaVariables.ReCaptchaSecretKey;
    string responseString = null;
    var dictionary = new Dictionary<string, string>
            {
                { "secret", recaptchaSecretKey },
                { "response", responseToken }
            };
    var postContent = new FormUrlEncodedContent(dictionary);
    using (var httpClient = new HttpClient())
    {
        try
        {
            HttpResponseMessage respons = httpClient.PostAsync(apiAddress, postContent).Result;
            responseString = respons.Content.ReadAsStringAsync().Result;
        }
        catch
        {
            //Todo: Error handling process goes here  
        }
    }
    return responseString;
}
解决方法

1. 实时生成AJAX请求的令牌

reCaptcha v3令牌仅单次有效且有效期短,原表单绑定的逻辑适合同步提交,但AJAX场景下易出现令牌过期或重复使用的问题。修改JS逻辑,在AJAX发起前实时获取令牌:

// 替换原表单绑定逻辑,改为AJAX专用提交函数
function submitAjaxForm() {
    grecaptcha.ready(function() {
        // 替换为你的站点密钥和业务场景
        grecaptcha.execute('你的ReCaptcha站点密钥', {action: 'ajax_submit'}).then(function(token) {
            $.ajax({
                url: '/Controller/Action', // 替换为你的后端接口地址
                type: 'POST',
                data: {
                    // 传递表单其他数据,以及新生成的令牌
                    responseToken: token,
                    // 其他字段示例:username: $('#username').val()
                },
                success: function(result) {
                    // 处理后端返回结果
                    console.log(result);
                },
                error: function(xhr) {
                    // 处理错误
                }
            });
        });
    });
}

2. 确保令牌完整传递

在浏览器控制台打印要传递的令牌值,或在后端ReCaptchaVerify方法开头添加日志,确认responseToken参数是完整的字符串,没有被截断或为空。

3. 添加用户IP参数(优化验证精度)

Google reCaptcha支持传递用户真实IP,缺少该参数可能降低验证通过率。修改后端验证代码:

public string ReCaptchaVerify(string responseToken)
{
    const string apiAddress = "https://www.google.com/recaptcha/api/siteverify";
    string recaptchaSecretKey = GoogleReCaptchaVariables.ReCaptchaSecretKey;
    string responseString = null;
    var dictionary = new Dictionary<string, string>
            {
                { "secret", recaptchaSecretKey },
                { "response", responseToken },
                // 添加用户IP参数
                { "remoteip", System.Web.HttpContext.Current.Request.UserHostAddress }
            };
    var postContent = new FormUrlEncodedContent(dictionary);
    using (var httpClient = new HttpClient())
    {
        try
        {
            HttpResponseMessage respons = httpClient.PostAsync(apiAddress, postContent).Result;
            responseString = respons.Content.ReadAsStringAsync().Result;
        }
        catch
        {
            //Todo: Error handling process goes here  
        }
    }
    return responseString;
}

4. 检查域名权限

登录Google reCaptcha控制台,确认你的项目域名(包括本地开发的localhost:端口号)已添加到允许列表,跨域情况下令牌会被判定无效。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 14:30:39