簡體   English   中英

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

[英]reCAPTCHA v3 token generation after submitting form in ASP.NET Core using 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>

我試圖在表單提交上阻止Default,然后在加載令牌后在表單上調用submitrequestSubmit ,這兩個實例都將導致preventDefault 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"禁用防偽請求驗證,但通過更多閱讀認為這不應該這樣做,因為也 沒有充分的理由
我怎樣才能做到這一點
編輯
即使設置表單屬性asp-antiforgery="false" ,我仍然收到以下錯誤。

防偽令牌驗證失敗。 所需的防偽請求令牌未在表單字段“__RequestVerificationToken”或 header 值“RequestVerificationToken”中提供。

更新
為了澄清,我可以通過在頁面加載時生成一個令牌並每 90 秒刷新一次令牌來解決這個問題,如下面的代碼所示。 但是,我不想 go 這條路線。 有沒有辦法只在提交后添加令牌的值?

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 Core Automatic Tag Helper添加 AntiForgery 令牌沒有發生。 (您可以通過查看源代碼並查找 AntiForgery 令牌來驗證此理論)

如果您不使用表單標簽上的asp-樣式元素來使用標簽助手,您將需要使用類似這樣的方式手動添加驗證令牌

@Html.AntiForgeryToken()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM