在ASP中提交表单后生成reCAPTCHA v3令牌.NET核心使用Javascript



我试图专门实现在表单提交后只设置令牌值的操作,而不是在页面加载时设置值,并在令牌到期前每隔90秒左右重置令牌。这两个stackoverflow问题在这方面没有帮助,请看这里和这里。
例如,这是我的表格:

<form id="contact" method="post">
<input type="hidden" asp-for="Token" />
<p><label asp-for="Name">Name</label> <input type="text" asp-for="Name" required /></p>
<p><label asp-for="Company">Company</label> <input type="text" asp-for="Company" /></p>
<p><label asp-for="EmailAddress">Email</label> <input type="email" asp-for="EmailAddress" required /></p>
<p><label asp-for="PhoneNumber">Phone</label> <input type="tel" asp-for="PhoneNumber" required /></p>
<p><label asp-for="Message">Message</label> <textarea asp-for="Message" required></textarea></p>
<p><input type="submit" value="Send" id="submit"/></p>
</form>

我尝试在表单提交中调用preventDefault,然后在加载令牌后在表单上调用submitrequestSubmit,这两个实例都将导致Antiforgery token validation failed问题,如本文所述。对于我的JS部分,我正在等待准备加载库,然后我将使用它将侦听器绑定到表单提交事件,然后在表单提交时执行:

grecaptcha.ready(function() {
document.getElementById("contact").addEventListener("submit", function(e) {
e.preventDefault();
grecaptcha.execute("@Model.reCaptchaSiteKey", {action: "contact"}).then(function(token) {
document.getElementById("Token").value = token;
document.getElementById("contact").requestSubmit((document.getElementById("submit"));
});
});
});

我还试图使用表单属性asp-antiforgery="false"禁用防目标请求验证,但通过更多的阅读,我认为这不应该这样做,因为也没有充分的理由。
我怎样才能做到这一点
EDIT
即使设置了表单属性asp-antiforgery="false",我仍然会收到以下错误。

Antiforgery令牌验证失败。所需的防伪造请求令牌没有以任一形式字段"提供__RequestVerificationToken";或标题值";RequestVerificationToken";。

UPDATE
为了澄清,我可以通过在页面加载时生成一个令牌并每90秒刷新一次令牌来实现这一点,如下面的代码所示。但是,我不想走这条路。难道没有一种方法只在提交后添加令牌的值吗?

grecaptcha.ready(function() {
grecaptcha.execute("@Model.reCaptchaSiteKey", {action: "submit"}).then(function(token) {
document.getElementById("Token").value = token;
});
});
setInterval(() => {
grecaptcha.ready(function() {
grecaptcha.execute("@Model.reCaptchaSiteKey", {action: "submit"}).then(function(token) {
document.getElementById("Token").value = token;
});
});
}, 90 * 1000);  

为了解决这个问题
我已经解决了这个问题,问题是我在按下输入按钮提交表单时阻止了表单的默认操作。在这样做的时候,表单中的数据仍然被发送到后端,因此,我是否在之后添加令牌值无关紧要,因为后端已经填充了空白的令牌
为了解决这个问题,我阻止了点击时输入按钮的默认操作,然后添加了令牌值,然后重新提交了输入为submitter的表单,如下所示:

<script>
grecaptcha.ready(function() {
let form = document.getElementById("contact");
let submitBtn = document.getElementById("sub-btn");
submitBtn.addEventListener("click", function(event) {
event.preventDefault();
grecaptcha.execute("@Model.reCaptchaSiteKey", {action: "contact"}).then(function(token) {
document.getElementById("Token").value = token;
form.requestSubmit(submitBtn);
});
});
});
</script>

表单上的输入按钮如下:

<p><input type="submit" value="Send" id="sub-btn" /></p>

由于您只是使用一个通用表单(下面示例中的代码段(

<form id="contact" method="post">

ASP。NET核心自动标记帮助程序添加的反伪造令牌没有发生。(你可以通过查看来源并寻找反伪造代币来验证这一理论(

如果您没有在表单标签上使用asp-样式元素的标签助手,则需要使用类似的东西手动添加验证令牌

@Html.AntiForgeryToken()

最新更新