My page has...
@page "{candidateId:int}"
... and
@Html.AntiForgeryToken()
Model has...
public void OnGet(int candidateId)
{
}
public void OnPost(int candidateId)
{
}
GET works fine. Here is my AJAX request..
$.ajax({
type: "POST",
url: "/Skills/" + candidateId,
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
data: {
name: 'hi mum'
},
success: function (response) {
},
failure: function (response) {
alert(response);
}
});
Browser receives useless error message... 400 Bad Request.
What am I missing?
You are getting a 400 (Bad Request) response because the framework expects the RequestVerificationToken
as part of the posted request.The framework uses this to prevent possible CSRF attacks. If your request does not have this information, the framework will return the 400 bad request. Your current code is not sending it.
Change the code to this
headers:
{
"RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val()
},
This will add a new item with key RequestVerificationToken
to the request header and the framework should not throw a 400 response when the call is made. (assuming your view code generated the hidden input for the __RequestVerificationToken
hidden input)
You can make the code more robust by injecting the IAntiforgery
implementation to the view/page and using the GetAndStoreTokens
method.
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
public string GetAntiXsrfRequestToken()
{
return Xsrf.GetAndStoreTokens(Model.HttpContext).RequestToken;
}
}
and call this GetAntiXsrfRequestToken
function to get the value in your javascript
headers:
{
"RequestVerificationToken": '@GetAntiXsrfRequestToken()'
},
You also probably want to use the PageModel's CandidateId
property to create the url. Something like this
url: "/Skills/@Model.CandidateId",
Also, you do need to call @Html.AntiForgeryToken()
method explicitly to generate the token input. Having a form with post method with no action attribute value will generate the hidden input for you.
<form method="post">
<!-- your inputs-->
</form>