c# - Async 函数和 BitArmory ReCaptcha 的问题
问题描述
我正在为我的联系表单使用Google ReCaptcha和BitArmory NuGet包。我检查了 Azure 上的日志,发现有些人从 BitArmory ReCaptcha 收到错误响应(siteKey: can not be null??)。
我尝试了多种方法来存储我的站点密钥。一开始就在我常用的全局变量中。接下来,我在函数中创建了一个本地字符串变量并插入到验证码函数中。最后一步是将我的站点密钥字符串硬编码为验证码。在所有情况下,结果相同,有些人仍然收到关于siteKey:can not be null 的响应?
这是我的表单的一部分:
@section head {
<script src="https://www.google.com/recaptcha/api.js?render=xxxxxxx"></script>
}
<form id="contactForm" class="form-horizontal" role="form" method="post" action="/site/comments">
<div class="form-group">
<label for="captcha"></label>
<input id="captcha" class="form-control" type="hidden" name="captcha" value=""/>
</div>
<div class="form-group">
<label for="email" class="col-lg-2 control-label">Email</label>
<div class="col-lg-10">
<input id="email" type="text" class="form-control" value="@ViewBag.Email" name="email" placeholder="me@email.com"/>
</div>
</div>
div class="col-lg-10">
<input type="submit" id="submitBtn" onclick="SubmitClicked()" class="btn btn-primary" value="Send us your feedback!"/>
</div>
<script type="text/javascript">
function SubmitClicked() {
$("#submitBtn").attr('disabled', true);
ExecuteReCaptcha();
}
function ExecuteReCaptcha() {
grecaptcha.ready(function() {
grecaptcha.execute('xxxxxxxx', {action: 'xxxxx'})
.then(function(token) {
// Set `token` in a hidden form input.
$("#captcha").val(token);
// POST Form
postForm();
});
});
}
function postForm() {
$("#contactForm").submit();
我的服务器端:
[HttpPost]
public async Task<ActionResult> Comments(string email, string captcha, string regarding, string comment)
{
var clientIp = Request.UserHostAddress;
var token = captcha;
var secret = "xxxxxxxxx";
var captchaApi = new ReCaptchaService();
var results = await captchaApi.Verify3Async(token, clientIp, secret);
if (IsValidEmail(email) && (!results.IsSuccess || results.Score < 0.5 || results.Action != "xxxxxx"))
{
ErrorViewModel eVm = new ErrorViewModel
{
message = "\"" + email + "\" is not a valid email address.",
bShowBackButton = true
};
return View("Error", eVm);
}
一些客户得到了回应:
System.ArgumentException: The client response must not be null or empty
Parameter name: siteSecret
at BitArmory.ReCaptcha.ReCaptchaService.<Verify3Async>d__12.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at BootstrappingMVC.Controllers.SiteController.<Comments>d__37.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Mvc.Async.TaskAsyncActionDescriptor.EndExecute(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass37.<BeginInvokeAsynchronousActionMethod>b__36(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<>c__DisplayClass2b.<BeginInvokeAction>b__1c()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult)
解决方案
这与你的siteSecret
. BitArmory.Recaptcha 代码( GitHub )中有一个错误:
public virtual async Task<ReCaptcha3Response> Verify3Async(string clientToken, string remoteIp, string siteSecret, CancellationToken cancellationToken = default)
{
if( string.IsNullOrWhiteSpace(siteSecret) ) throw new ArgumentException("The secret must not be null or empty", nameof(siteSecret));
if( string.IsNullOrWhiteSpace(clientToken) ) throw new ArgumentException("The client response must not be null or empty", nameof(siteSecret));
即使消息提供了正确的原因,这两种if
说法都会引发ArgumentException
指责。siteSecret
在您的情况下,它token
是空的,而不是secret
.
至于为什么令牌可以为空,我认为这是因为您没有阻止默认处理您的按钮单击,该按钮在grecaptcha
执行之前提交表单。
尝试SubmitClicked
如下修改您的功能:
function SubmitClicked(e) {
e.preventDefault();
$("#submitBtn").attr('disabled', true);
ExecuteReCaptcha();
}
推荐阅读
- amazon-web-services - EC2 实例 Web 服务器站点作为 Squarespace 站点的子域?
- windows - AHK:使用 RandomBezier 函数
- python - 如何在 Python 中制作堆积条形图?
- ios - 添加新行并填充它的问题
- python - 更新字典中键的值
- batch-file - 在多行中查找多个字符串
- javascript - 如何将 datepicker 的下拉列表重新定位到输入表单上方?
- java - 在 minecraft 插件中创建自定义 YML 文件
- python - 以脚本化 curl 打印输出 - Python
- r - 如何计算纬度的余弦作为网格降水值的权重?