C# .NET 9.0 Blazor server component for hCaptcha.
$ dotnet add package ChatAIze.CaptchaC# .NET 10.0 Blazor Server component for hCaptcha.
[!WARNING] This library is designed for Blazor Server with interactive rendering enabled. It does NOT support Blazor WebAssembly.
@rendermode InteractiveServer)https://js.hcaptcha.com/1/api.jshttps://hcaptcha.com/siteverifydotnet add package ChatAIze.Captcha
Install-Package ChatAIze.Captcha
// Program.cs
builder.Services.AddCaptcha(o =>
{
o.SiteKey = builder.Configuration["Captcha:SiteKey"]!;
o.Secret = builder.Configuration["Captcha:Secret"]!;
});
app.UseCaptcha();
// App.razor (or index.html)
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
// Any .razor component
@rendermode InteractiveServer
<Captcha @bind-IsVerified="_isVerified" />
@code {
private bool _isVerified;
}
builder.Services.AddCaptcha(o =>
{
o.SiteKey = builder.Configuration["Captcha:SiteKey"]!;
o.Secret = builder.Configuration["Captcha:Secret"]!;
o.VerifyIpAddresses = false; // optional, default is false
o.IsConnectionProxied = false; // optional, default is false
});
[!NOTE] If users connect through a reverse proxy (Cloudflare, Nginx, etc.), set
IsConnectionProxied = trueand ensure your proxy is configured to send a trustedX-Forwarded-Forheader.
{
"Captcha": {
"SiteKey": "YOUR_SITE_KEY",
"Secret": "YOUR_SECRET"
}
}
# Prefer environment variables for secrets in production
Captcha__SiteKey=YOUR_SITE_KEY
Captcha__Secret=YOUR_SECRET
app.UseCaptcha();
[!NOTE] If you use
UseForwardedHeaders, call it beforeUseCaptcha()so the IP is already resolved.app.UseForwardedHeaders(); app.UseCaptcha();Docs: https://learn.microsoft.com/aspnet/core/host-and-deploy/proxy-load-balancer
<head>
<!-- ... -->
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
<!-- ... -->
</head>@using ChatAIze.Captcha@rendermode InteractiveServer
<Captcha @bind-IsVerified="_isVerified" />
<p>Verified: @_isVerified</p>
@code {
private bool _isVerified;
}<Captcha
@bind-IsVerified="_isVerified"
Succeeded="OnSucceeded"
Expired="OnExpired"
Error="OnError" />
@code {
private bool _isVerified;
private void OnSucceeded() { }
private void OnExpired() { }
private void OnError(string code) { }
}<Captcha
@bind-IsVerified="_isVerified"
SiteKey="YOUR_SITE_KEY"
Secret="YOUR_SECRET" /><Captcha
@bind-IsVerified="_isVerified"
Theme="CaptchaTheme.Auto"
Size="CaptchaSize.Normal" />builder.Services.AddCaptcha(o =>
{
o.SiteKey = "...";
o.Secret = "...";
o.VerifyIpAddresses = true;
o.IsConnectionProxied = true; // set to true if behind a proxy
});[!WARNING] Only enable IP verification if you understand the privacy implications and your proxy setup is trusted.
Secret to the client; it must stay server-side.X-Forwarded-For is trusted and not spoofable.IsVerified on the server before sensitive operations.https://js.hcaptcha.com and hCaptcha-related endpoints.CaptchaOptions
SiteKey (required): hCaptcha site key.Secret (required): hCaptcha secret key.VerifyIpAddresses (optional): Include client IPs in verification requests.IsConnectionProxied (optional): Read IPs from X-Forwarded-For when behind a proxy.Captcha
IpAddress: Optional IP override for verification.SiteKey: Optional site key override.Secret: Optional secret override.Theme: Auto, Light, Dark.Size: Normal, Compact.IsVerified: Two-way bound verification state.Opened, Closed, Succeeded, Expired, ChallengeExpired, Error.IsVerified and re-check before processing server actions.Secret on the server only; never expose it to client code.VerifyIpAddresses only when required by your security policy.X-Forwarded-For comes from a trusted source and is properly configured.Expired and Error to prompt users to retry.api.js.X-Forwarded-For is used as-is when proxied; if multiple IPs are present, configure your proxy to send a single, trusted client IP.api.js is included and the component uses interactive rendering.SiteKey and Secret match your hCaptcha settings and that the server can reach https://hcaptcha.com/siteverify.X-Forwarded-For is trustworthy and not being overwritten by untrusted clients.| Code | Description |
|---|---|
| rate-limited | User has sent too many requests |
| network-error | There are network connection issues (e.g., offline). hCaptcha will automatically retry. |
| invalid-data | Invalid data is not accepted by endpoints |
| challenge-error | Challenge encountered error on setup. User may need to select the checkbox or call execute. |
| challenge-closed | User closed the challenge |
| challenge-expired | Time limit to answer challenge has expired |
| missing-captcha | No captcha was found. Verify hCaptcha was properly setup and a captcha was rendered. |
| invalid-captcha-id | Captcha does not exist for ID provided. Check that the captcha rendered matches the stored ID. |
| internal-error | hCaptcha client encountered an internal error. User may need to select the checkbox or call execute. |
| script-error | hCaptcha JS SDK could not be loaded. User may be behind a firewall blocking api.js. |