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

在.NET Web API+Angular集成Google reCAPTCHA v3时遇invalid-input-response错误

Google reCAPTCHA v3集成问题:invalid-input-response错误

我正在将Google reCAPTCHA v3集成到.NET后端(ASP.NET Core)与Angular前端项目中。后端已实现captchaTokenVerify方法,通过Google reCAPTCHA API验证令牌,但收到返回结果:

{
  "success": false,
  "error-codes": ["invalid-input-response"]
}

前后端配置

.NET后端代码

public async Task<DataTable> captchaTokenVerify(string secret, string siteToken)
{
    DataTable dt = new DataTable();
    dt.Columns.Add("Success", typeof(bool));
    dt.Columns.Add("Score", typeof(decimal));
    dt.Columns.Add("ErrorMessage", typeof(string));

    try
    {
        var values = new Dictionary<string, string>
        {
            { "secret", secret },
            { "response", siteToken }
        };
        var content = new FormUrlEncodedContent(values);

        var response = await client.PostAsync("https://www.google.com/recaptcha/api/siteverify", content);
        response.EnsureSuccessStatusCode();

        var responseString = await response.Content.ReadAsStringAsync();
        var json = JObject.Parse(responseString);

        bool success = json["success"].Value<bool>();
        decimal score = json.ContainsKey("score") ? json["score"].Value<decimal>() : 0;
        string errorMessage = success ? null : json["error-codes"]?.ToString();

        dt.Rows.Add(success, score, errorMessage);

        return dt;
    }
    catch (Exception ex)
    {
        dt.Rows.Add(false, 0, $"Error: {ex.Message}");
        return dt;
    }
}

Angular前端代码

// Angular service
captchaTokenVerify(token: string) {
    console.log('tok', token);
    return this.http.get<any>(`${this.getBaseUrl()}Auth/captchaTokenVerify?secret=${environment.CAPTCHA_SECRET_KEY_V3}&siteToken=${token}`);
}

// Triggering reCAPTCHA verification
executeRecaptchaV3() {
    this.recaptchaV3Service.execute(environment.CAPTCHA_SECRET_KEY_V3, 'myAction', (token) => {
        this.authService.captchaTokenVerify(token).subscribe({
            next: (res) => {
                console.log('res', res);
            },
            error: (err) => {
                this.notification.showError('Oops!', validateForm.getErrorMessage(err));
            },
        });
    });
}

已尝试的排查步骤

  • 验证令牌:确认前端通过recaptchaV3Service.execute生成了有效令牌
  • 编码格式:后端使用FormUrlEncodedContent确保数据为application/x-www-form-urlencoded格式
  • 密钥校验:确认使用的是Google reCAPTCHA控制台中的正确密钥

疑问

  1. 引发invalid-input-response错误的可能原因是什么?
  2. 前后端配置中是否存在遗漏环节导致该错误?

问题分析与解决方案

1. invalid-input-response错误的常见原因

  • 令牌过期:reCAPTCHA v3令牌有效期仅2分钟,超时验证会触发该错误
  • 令牌无效/重复使用:令牌被篡改、重复提交,或不是由对应站点密钥生成
  • 密钥不匹配:后端用的密钥与前端生成令牌的站点密钥不配对(比如混用v2/v3密钥,或站点密钥和密钥搞反)
  • 参数传递错误:response参数未传递完整令牌,或存在编码异常
  • 服务器访问限制:你的服务器IP被Google临时限制,无法正常发起验证请求

2. 你的代码中存在的关键问题

  • 前端execute方法参数错误:recaptchaV3Service.execute的第一个参数应该是站点密钥(site key),你现在传的是密钥(secret key),导致生成的令牌本身无效
  • GET请求暴露密钥:将密钥拼在URL参数中传递,会泄露敏感信息,同时可能被Google判定为异常请求
  • 后端返回DataTable设计不合理:增加前后端解析复杂度,建议改用强类型DTO

修复步骤

  1. 修正前端令牌生成逻辑:
    替换execute方法的第一个参数为站点密钥:

    executeRecaptchaV3() {
        // 使用站点密钥而非密钥
        this.recaptchaV3Service.execute(environment.CAPTCHA_SITE_KEY_V3, 'myAction', (token) => {
            this.authService.captchaTokenVerify(token).subscribe({
                next: (res) => console.log('res', res),
                error: (err) => this.notification.showError('Oops!', validateForm.getErrorMessage(err))
            });
        });
    }
    
  2. 修改前端API请求方式:
    改用POST请求,仅传递令牌,密钥由后端从配置读取:

    // Angular service
    captchaTokenVerify(token: string) {
        console.log('tok', token);
        return this.http.post<any>(`${this.getBaseUrl()}Auth/captchaTokenVerify`, { token });
    }
    
  3. 更新后端代码:
    从配置读取密钥,改用强类型DTO接收和返回数据:

    // 定义返回结果DTO
    public class CaptchaVerifyResult
    {
        public bool Success { get; set; }
        public decimal Score { get; set; }
        public string ErrorMessage { get; set; }
    }
    
    // 接收请求的DTO
    public class CaptchaVerifyRequest
    {
        public string Token { get; set; }
    }
    
    [HttpPost]
    public async Task<CaptchaVerifyResult> CaptchaTokenVerify([FromBody] CaptchaVerifyRequest request)
    {
        try
        {
            // 从配置读取密钥,禁止前端传递
            var secret = _configuration["Captcha:SecretKeyV3"];
            var values = new Dictionary<string, string>
            {
                { "secret", secret },
                { "response", request.Token }
            };
            var content = new FormUrlEncodedContent(values);
    
            var response = await _httpClient.PostAsync("https://www.google.com/recaptcha/api/siteverify", content);
            response.EnsureSuccessStatusCode();
    
            var responseString = await response.Content.ReadAsStringAsync();
            var json = JObject.Parse(responseString);
    
            bool success = json["success"].Value<bool>();
            decimal score = json.ContainsKey("score") ? json["score"].Value<decimal>() : 0;
            string errorMessage = success ? null : string.Join(", ", json["error-codes"].Values<string>());
    
            return new CaptchaVerifyResult
            {
                Success = success,
                Score = score,
                ErrorMessage = errorMessage
            };
        }
        catch (Exception ex)
        {
            return new CaptchaVerifyResult
            {
                Success = false,
                Score = 0,
                ErrorMessage = $"Error: {ex.Message}"
            };
        }
    }
    
  4. 额外校验项:

    • 确认后端用的是reCAPTCHA v3的密钥,前端用的是对应的站点密钥
    • 确保令牌生成后立即发起验证,避免过期
    • 检查服务器是否能正常访问Google验证API,无防火墙/代理拦截

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 12:28:14