Reputation: 3024
Is it possible to have antiforgery tokens without forms? I have an ajax post call that I would like to make that needs an antiforgery token. However, most examples I have seen are asking for forms. This is what I have so far:
<script>
$(document).ready(function () {
var SessionId = document.getElementById("Id").value;
var form_data = {
"SessionId": SessionId
};
$.ajax({
url: "@Url.Action("GetHistory", @ViewContext.RouteData.Values["controller"].ToString())",
method: "POST",
data: JSON.stringify(form_data),
contentType: "application/json",
success: function (result) {
console.log(result);
var output = JSON.parse(result);
for (var i = 0; i < output.length; i++) {
var p = document.createElement("span");
var q = document.createElement("li");
if (output[i].Mine == true) {
p.setAttribute("class", "Sender Me");
q.setAttribute("class", "Message");
} else {
p.setAttribute("class", "Sender");
q.setAttribute("class", "Message");
}
p.textContent = output[i].Name + " - " + moment(output[i].CreatedOn).format("DD-MM-YYYY HH:mm:ss");
q.textContent = output[i].Message;
document.getElementById("MessageList").appendChild(p);
document.getElementById("MessageList").appendChild(q);
}
},
error: function (error) {
console.log(error);
}
});
$('#MessageList').stop().animate({
scrollTop: $('#MessageList')[0].scrollHeight
}, 2000);
return false;
});
</script>
This just gets its input from a textbox and a button that is not attached to a form.
Upvotes: 0
Views: 3389
Reputation: 20116
Ajax request could send the anti-forgery token in request header to the server.Refer to solution in Handle Ajax Requests in ASP.NET Core Razor Pages.
<script type="text/javascript">
function gettoken() {
var token = '@Html.AntiForgeryToken()';
token = $(token).val();
return token;
}
</script>
<script>
$(document).ready(function () {
var SessionId = document.getElementById("Id").value;
var form_data = {
"SessionId": SessionId
};
var headers = {};
headers['XSRF-TOKEN'] = gettoken();//header name could be changed
$.ajax({
url: "/Home/testPost",
method: "POST",
data: JSON.stringify(form_data),
headers:headers,
contentType: "application/json",
success: function (result) {
console.log(result);
//...
},
error: function (error) {
console.log(error);
}
});
//...
});
Then you need to configure the antiforgery service to look for the XSRF-TOKEN
header you have defined:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
}
Of course,you need to use correct model binding and [ValidateAntiForgeryToken]
attribute for your action.
Upvotes: 1
Reputation: 379
You need to add it manually. Try this:
var token = $("[name='__RequestVerificationToken']").val();
And then post it with your data:
data: {
__RequestVerificationToken: token,
JSON.stringify(form_data)
}
EDIT:
As @AndresAbel mentioned, you can copy the token from the form and send it in ajax post:
@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "__AjaxAntiForgeryForm" }))
{
@Html.AntiForgeryToken()
}
Then in in your script:
var token = $('input[name="__RequestVerificationToken"]', $('#__AjaxAntiForgeryForm')).val();
Then send it in ajax:
data: {
__RequestVerificationToken: token,
JSON.stringify(form_data)
}
Don't forget to add the annotation [ValidateAntiForgeryToken]
for your method in the controller.
Upvotes: 0
Reputation: 69260
The AntiforgeryToken is there to prevent cross site request forgery. So you should really use it. The easiest way to get one in jQuery is to render a dummy, hidden form on the page. Then the you can use your javaScript to copy the token from the dummy form and include it in your ajax post.
Upvotes: 0