inclure anti-forgerytoken dans ajax post ASP.NET MVC
j'ai des problèmes avec l'Anti-Forgerytoken avec ajax. J'utilise ASP.NET MVC 3. J'ai essayé la solution dans jQuery appels Ajax et le Html.AntiForgeryToken () . En utilisant cette solution, le jeton est maintenant passé:
var data = { ... } // with token, key is '__RequestVerificationToken'
$.ajax({
type: "POST",
data: data,
datatype: "json",
traditional: true,
contentType: "application/json; charset=utf-8",
url: myURL,
success: function (response) {
...
},
error: function (response) {
...
}
});
quand je supprime l'attribut [ValidateAntiForgeryToken]
juste pour voir si les données (avec le token) sont passées comme paramètres au contrôleur, je peux voir qu'elles sont passées. Mais pour une raison quelconque, le Le message A required anti-forgery token was not supplied or was invalid.
apparaît quand j'ai remis l'attribut en place.
des idées?
MODIFIER
l'anti-forgerytoken est généré à l'intérieur d'un formulaire, mais je n'utilise pas une action Soumettre pour le soumettre. Au lieu de cela, je suis juste obtenir la valeur du jeton en utilisant jquery et ensuite essayer d'ajax poster cela.
voici le formulaire qui contient le jeton, et se trouve à la page principale:
<form id="__AjaxAntiForgeryForm" action="#" method="post">
@Html.AntiForgeryToken()
</form>
9 réponses
vous avez incorrectement spécifié le contentType
à application/json
.
Voici un exemple de comment cela fonctionne.
contrôleur:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(string someValue)
{
return Json(new { someValue = someValue });
}
}
:
@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "__AjaxAntiForgeryForm" }))
{
@Html.AntiForgeryToken()
}
<div id="myDiv" data-url="@Url.Action("Index", "Home")">
Click me to send an AJAX request to a controller action
decorated with the [ValidateAntiForgeryToken] attribute
</div>
<script type="text/javascript">
$('#myDiv').submit(function () {
var form = $('#__AjaxAntiForgeryForm');
var token = $('input[name="__RequestVerificationToken"]', form).val();
$.ajax({
url: $(this).data('url'),
type: 'POST',
data: {
__RequestVerificationToken: token,
someValue: 'some value'
},
success: function (result) {
alert(result.someValue);
}
});
return false;
});
</script>
l'Autre (moins javascriptish) approche, que j'ai fait, va quelque chose comme ceci:
tout d'Abord, un helper Html
public static MvcHtmlString AntiForgeryTokenForAjaxPost(this HtmlHelper helper)
{
var antiForgeryInputTag = helper.AntiForgeryToken().ToString();
// Above gets the following: <input name="__RequestVerificationToken" type="hidden" value="PnQE7R0MIBBAzC7SqtVvwrJpGbRvPgzWHo5dSyoSaZoabRjf9pCyzjujYBU_qKDJmwIOiPRDwBV1TNVdXFVgzAvN9_l2yt9-nf4Owif0qIDz7WRAmydVPIm6_pmJAI--wvvFQO7g0VvoFArFtAR2v6Ch1wmXCZ89v0-lNOGZLZc1" />
var removedStart = antiForgeryInputTag.Replace(@"<input name=""__RequestVerificationToken"" type=""hidden"" value=""", "");
var tokenValue = removedStart.Replace(@""" />", "");
if (antiForgeryInputTag == removedStart || removedStart == tokenValue)
throw new InvalidOperationException("Oops! The Html.AntiForgeryToken() method seems to return something I did not expect.");
return new MvcHtmlString(string.Format(@"{0}:""{1}""", "__RequestVerificationToken", tokenValue));
}
qui retournera une chaîne de caractères
__RequestVerificationToken:"P5g2D8vRyE3aBn7qQKfVVVAsQc853s-naENvpUAPZLipuw0pa_ffBf9cINzFgIRPwsf7Ykjt46ttJy5ox5r3mzpqvmgNYdnKc1125jphQV0NnM5nGFtcXXqoY3RpusTH_WcHPzH4S4l1PmB8Uu7ubZBftqFdxCLC5n-xT0fHcAY1"
si nous pouvons l'utiliser comme ceci
$(function () {
$("#submit-list").click(function () {
$.ajax({
url: '@Url.Action("SortDataSourceLibraries")',
data: { items: $(".sortable").sortable('toArray'), @Html.AntiForgeryTokenForAjaxPost() },
type: 'post',
traditional: true
});
});
});
et ça a l'air de marcher!
c'est si simple! lorsque vous utilisez @Html.AntiForgeryToken()
dans votre code html cela signifie que le serveur a signé cette page et chaque requête envoyée au serveur à partir de cette page particulière a un signe qui est empêché d'envoyer une fausse requête par les pirates. ainsi, pour que cette page soit authentifiée par le serveur, vous devez passer par deux étapes:
1.envoyer un paramètre nommé __RequestVerificationToken
et pour obtenir sa valeur utiliser les codes ci-dessous:
<script type="text/javascript">
function gettoken() {
var token = '@Html.AntiForgeryToken()';
token = $(token).val();
return token;
}
</script>
par exemple prendre un appel ajax
$.ajax({
type: "POST",
url: "/Account/Login",
data: {
__RequestVerificationToken: gettoken(),
uname: uname,
pass: pass
},
dataType: 'json',
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
success: successFu,
});
et étape 2 Il suffit de décorer votre méthode d'action par [ValidateAntiForgeryToken]
function DeletePersonel(id) { var data = new FormData(); data.append("__RequestVerificationToken", "@HtmlHelper.GetAntiForgeryToken()"); $.ajax({ type: 'POST', url: '/Personel/Delete/' + id, data: data, cache: false, processData: false, contentType: false, success: function (result) { } }); } public static class HtmlHelper { public static string GetAntiForgeryToken() { System.Text.RegularExpressions.Match value = System.Text.RegularExpressions.Regex.Match(System.Web.Helpers.AntiForgery.GetHtml().ToString(), "(?:value=\")(.*)(?:\")"); if (value.Success) { return value.Groups[1].Value; } return ""; } }
je sais que c'est une vieille question. Mais je vais ajouter ma réponse de toute façon, pourrait aider quelqu'un comme moi.
si vous ne voulez pas traiter le résultat de l'action post du contrôleur, comme appeler la méthode LoggOff
de Accounts
contrôleur, vous pouvez faire comme la version suivante de la réponse de @DarinDimitrov:
@using (Html.BeginForm("LoggOff", "Accounts", FormMethod.Post, new { id = "__AjaxAntiForgeryForm" }))
{
@Html.AntiForgeryToken()
}
<!-- this could be a button -->
<a href="#" id="ajaxSubmit">Submit</a>
<script type="text/javascript">
$('#ajaxSubmit').click(function () {
$('#__AjaxAntiForgeryForm').submit();
return false;
});
</script>
j'ai essayé beaucoup d'exercices et aucun d'eux n'a travaillé pour moi. L'exception était "le champ de formulaire anti-contrefaçon requis "_ _ _ RequestVerificationToken".
ce qui m'a aidé était de changer de forme .l'ajax .post:
$.post(
url,
$(formId).serialize(),
function (data) {
$(formId).html(data);
});
In Asp.Net MVC lorsque vous utilisez @Html.AntiForgeryToken()
Razor crée un champ d'entrée caché avec le nom __RequestVerificationToken
pour stocker des jetons. Si vous voulez écrire une implémentation AJAX, vous devez récupérer ce token vous-même et le passer comme paramètre au serveur pour qu'il puisse être validé.
Étape 1: Obtenir le jeton
var token = $('input[name="`__RequestVerificationToken`"]').val();
Étape 2: Passer le jeton dans L'appel AJAX
function registerStudent() {
var student = {
"FirstName": $('#fName').val(),
"LastName": $('#lName').val(),
"Email": $('#email').val(),
"Phone": $('#phone').val(),
};
$.ajax({
url: '/Student/RegisterStudent',
type: 'POST',
data: {
__RequestVerificationToken:token,
student: student,
},
dataType: 'JSON',
contentType:'application/x-www-form-urlencoded; charset=utf-8',
success: function (response) {
if (response.result == "Success") {
alert('Student Registered Succesfully!')
}
},
error: function (x,h,r) {
alert('Something went wrong')
}
})
};
Note : le contenu le type doit être 'application/x-www-form-urlencoded; charset=utf-8'
j'ai téléchargé le projet sur Github, vous pouvez le télécharger et de l'essayer.
utilisez la fonction ci-dessous:
function AjaxPostWithAntiForgeryToken(destinationUrl, successCallback) {
var token = $('input[name="__RequestVerificationToken"]').val();
var headers = {};
headers["__RequestVerificationToken"] = token;
$.ajax({
type: "POST",
url: destinationUrl,
data: { __RequestVerificationToken: token }, // Your other data will go here
dataType: "json",
success: function (response) {
successCallback(response);
},
error: function (xhr, status, error) {
// handle failure
}
});
}
In Asp.Net vous pouvez demander le token directement, comme documenté :
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
public string GetAntiXsrfRequestToken()
{
return Xsrf.GetAndStoreTokens(Context).RequestToken;
}
}
et l'utiliser en javascript:
function DoSomething(id) {
$.post("/something/todo/"+id,
{ "__RequestVerificationToken": '@GetAntiXsrfRequestToken()' });
}
vous pouvez ajouter le filtre global recommandé, comme documenté :
services.AddMvc(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
})