I am using JQuery with ASP.NET Core 1.0.1 and I have the Ajax call:
$("#send-message").on("submit", function (event) {
event.preventDefault();
var $form = $(this);
$.ajax({
url: "api/messages",
data: JSON.stringify($form.serializeToJSON()),
dataType: "json",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
type: "post"
})
.done(function (data, status, xhr) { })
.fail(function (xhr, status, error) { });
To the ASP.NET Core action:
[HttpPost("messages")]
public async Task<IActionResult> Post([FromBody]MessagePostApiModelModel model) {
// Send message
}
The form is in a shared view and it is the following:
<form id="send-question" method="post">
<textarea name="content"></textarea>
<button class="button" type="submit">Enviar</button>
</form>
When I submit the form I get the error:
Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException: The required antiforgery header value "RequestVerificationToken" is not present.
How can I enable ASP.NET Core's AntiForgeryToken with JQuery Ajax calls?
UPDATE
I need to add the following asp-controller and asp-action to the form:
<form asp-controller="QuestionApi" asp-action="Post" id="send-question" method="post">
</form>
This will generate the antiforgery token. And I needed to manually add the token to the headers of the JQuery call as follows:
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"RequestVerificationToken": $form.find("input[name='af_token']").val()
},
Is there a better way to do this?
How do solve this when there is not form and I have only an A tag that when clicked makes the Ajax call? Can I generate a common antiforgery token on my page head to be used by all ajax calls from that page?
In ASP.Net Core anti forgery token is automatically added to forms, so you don't need to add @Html. AntiForgeryToken() if you use razor form element or if you use IHtmlHelper. BeginForm and if the form's method isn't GET. And when user submits form this token is verified on server side if validation is enabled.
You can protect users of your ASP.NET Core applications from CSRF attacks by using anti-forgery tokens. When you include anti-forgery tokens in your application, two different values are sent to the server with each POST. One of the values is sent as a browser cookie, and one is submitted as form data.
TYPE. __RequestVerificationToken. www.grpgroup.co.uk. This is an anti-forgery cookie set by web applications built using ASP.NET MVC technologies. It is designed to stop unauthorised posting of content to a website, known as Cross-Site Request Forgery.
mode777's answer just needs a small addition to make this work (I tried it):
$(document).ajaxSend(function(e, xhr, options) {
if (options.type.toUpperCase() == "POST") {
var token = $form.find("input[name='af_token']").val();
xhr.setRequestHeader("RequestVerificationToken", token);
}
});
Actually, if you also submit using Ajax, you don't need to use a form at all. Put this in your _layout:
<span class="AntiForge"> @Html.AntiForgeryToken() </span>
Then you pickup the token by adding this to your javascript:
$(document)
.ajaxSend(function (event, jqxhr, settings) {
if (settings.type.toUpperCase() != "POST") return;
jqxhr.setRequestHeader('RequestVerificationToken', $(".AntiForge" + " input").val())
})
The @HtmlAntiForgeryToken generates a hidden input field with the antiforgery token, the same as when using a form. The code above finds it using the class selector to select the span, then gets the input field inside that to collect the token and add it as a header.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With