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

Blazor WebAssembly中如何避免reCAPTCHA v3站点密钥暴露

解决Blazor WebAssembly中reCAPTCHA v3站点密钥可见的问题

首先要明确:reCAPTCHA v3的站点密钥(Site Key)本身就是设计为公开的,Google允许它出现在前端代码中。因为reCAPTCHA的核心验证逻辑是在你的后端完成的——你需要用保密的**密钥(Secret Key)**向Google发送验证请求,这个Secret Key才是必须严格保管、不能泄露的。即使用户看到了站点密钥,也无法伪造有效的验证请求,因为没有Secret Key的话,Google会拒绝验证。

如果出于某些原因你还是想让站点密钥不在静态页面源码中直接显示,可以尝试以下方案:

方案:动态加载reCAPTCHA脚本,从后端获取站点密钥

这个方案的核心是不在index.html中硬编码站点密钥,而是通过后端API动态获取,再在Blazor组件中动态加载reCAPTCHA脚本。

步骤1:后端添加获取站点密钥的API

以ASP.NET Core后端为例,在控制器中添加一个接口返回站点密钥(可添加简单的域名校验防止滥用):

[ApiController]
[Route("api/[controller]")]
public class ReCaptchaController : ControllerBase
{
    private readonly IConfiguration _configuration;

    public ReCaptchaController(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    [HttpGet("sitekey")]
    public IActionResult GetSiteKey()
    {
        // 可选:校验请求来源域名
        var origin = Request.Headers.Origin.ToString();
        if (!origin.Equals("你的前端域名", StringComparison.OrdinalIgnoreCase))
        {
            return Forbid();
        }
        
        var siteKey = _configuration["ReCaptcha:SiteKey"];
        return Ok(siteKey);
    }
}

步骤2:前端Blazor组件动态加载脚本并使用

在需要使用reCAPTCHA的组件中,先从后端获取站点密钥,再动态创建脚本标签加载reCAPTCHA:

@inject HttpClient Http
@implements IAsyncDisposable

<button @onclick="HandleSubmit">提交</button>

@code {
    private IJSObjectReference? _reCaptchaInstance;
    private string? _siteKey;

    protected override async Task OnInitializedAsync()
    {
        // 从后端获取站点密钥
        _siteKey = await Http.GetStringAsync("api/recaptcha/sitekey");
        
        // 动态加载reCAPTCHA脚本
        await JS.InvokeVoidAsync("window.loadReCaptchaScript", _siteKey);
        
        // 等待脚本加载完成(可替换为更可靠的加载监听逻辑)
        await Task.Delay(600);
        
        // 获取grecaptcha实例
        _reCaptchaInstance = await JS.InvokeAsync<IJSObjectReference>("getGrecaptchaInstance");
    }

    private async Task HandleSubmit()
    {
        if (_reCaptchaInstance == null || string.IsNullOrEmpty(_siteKey))
            return;
        
        // 调用reCAPTCHA获取验证令牌
        var token = await _reCaptchaInstance.InvokeAsync<string>("execute", _siteKey, new { action = "submit" });
        
        // 将token发送到后端完成最终验证
        await Http.PostAsJsonAsync("api/recaptcha/verify", new { Token = token });
    }

    public async ValueTask DisposeAsync()
    {
        if (_reCaptchaInstance != null)
        {
            await _reCaptchaInstance.DisposeAsync();
        }
    }
}

步骤3:添加前端辅助JS函数

在wwwroot目录下创建recaptcha.js文件,添加加载脚本的辅助函数:

window.loadReCaptchaScript = function(siteKey) {
    return new Promise((resolve, reject) => {
        const script = document.createElement('script');
        script.src = `https://www.google.com/recaptcha/api.js?render=${siteKey}`;
        script.async = true;
        script.defer = true;
        script.onload = () => resolve();
        script.onerror = () => reject(new Error('Failed to load reCAPTCHA script'));
        document.head.appendChild(script);
    });
};

window.getGrecaptchaInstance = function() {
    return grecaptcha;
};

然后在index.html中引入这个JS文件:

<script src="recaptcha.js"></script>

最后再强调:不要过度担心站点密钥的公开问题,只要你严格保管好后端的Secret Key,就不会有安全风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 05:17:24