включить antiforgerytoken в ajax post ASP.NET MVC
у меня возникли проблемы с AntiForgeryToken с ajax. Я использую ASP.NET MVC 3. Я попробовал решение в jQuery Ajax вызывает и Html.AntiForgeryToken(). Используя это решение, токен теперь передается:
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) {
...
}
});
когда я удалить [ValidateAntiForgeryToken]
атрибут просто чтобы увидеть, передаются ли данные (с токеном) в качестве параметров контроллеру, я вижу, что они передаются. Но по какой-то причине A required anti-forgery token was not supplied or was invalid.
сообщение все еще всплывает, когда я ставлю атрибут обратно.
какие идеи?
EDIT
antiforgerytoken генерируется внутри формы, но я не использую действие submit для его отправки. Вместо этого я просто получаю значение токена с помощью jquery, а затем пытаюсь опубликовать его в ajax.
вот форма, которая содержит маркер, и находится в верхней главной странице:
<form id="__AjaxAntiForgeryForm" action="#" method="post">
@Html.AntiForgeryToken()
</form>
9 ответов:
еще один (менее javascriptish) подход, который я сделал, идет что-то вроде этого:
во-первых, HTML helper
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)); }
это вернет строку
__RequestVerificationToken:"P5g2D8vRyE3aBn7qQKfVVVAsQc853s-naENvpUAPZLipuw0pa_ffBf9cINzFgIRPwsf7Ykjt46ttJy5ox5r3mzpqvmgNYdnKc1125jphQV0NnM5nGFtcXXqoY3RpusTH_WcHPzH4S4l1PmB8Uu7ubZBftqFdxCLC5n-xT0fHcAY1"
так что мы можем использовать его так
$(function () { $("#submit-list").click(function () { $.ajax({ url: '@Url.Action("SortDataSourceLibraries")', data: { items: $(".sortable").sortable('toArray'), @Html.AntiForgeryTokenForAjaxPost() }, type: 'post', traditional: true }); }); });
и это, кажется, работает!
это так просто! когда вы используете
@Html.AntiForgeryToken()
в вашем html-коде это означает, что сервер подписал эту страницу, и каждый запрос, отправленный на сервер с этой конкретной страницы, имеет знак, который предотвращает отправку поддельного запроса хакерами. поэтому для того, чтобы эта страница была аутентифицирована сервером, вы должны пройти два шага:1.отправьте параметр с именем
__RequestVerificationToken
и чтобы получить его значение используйте коды ниже:<script type="text/javascript"> function gettoken() { var token = '@Html.AntiForgeryToken()'; token = $(token).val(); return token; } </script>
например возьмите 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, });
и Шаг 2 просто украсьте свой метод действий с помощью
[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 ""; } }
Я знаю, это старый вопрос. Но я все равно добавлю свой ответ, может помочь кому-то вроде меня.
Если вы не хотите обрабатывать результат от действия post контроллера, например, вызывая
LoggOff
методAccounts
контроллер, вы могли бы сделать как следующую версию ответа @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>
Я пробовал много обходных путей и не из них работал для меня. Исключением стало "обязательное поле формы защиты от подделки "__RequestVerificationToken".
что помогло мне, так это переключить форму .AJAX для .сообщение:
$.post( url, $(formId).serialize(), function (data) { $(formId).html(data); });
In Asp.Net MVC при использовании
@Html.AntiForgeryToken()
Razor создает скрытое поле ввода с именем__RequestVerificationToken
для хранения маркеров. Если вы хотите написать реализацию AJAX, вы должны сами получить этот токен и передать его в качестве параметра на сервер, чтобы его можно было проверить.Шаг 1: получить знак
var token = $('input[name="`__RequestVerificationToken`"]').val();
Шаг 2: передайте токен в вызов 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') } }) };
Примечание тип контента должен быть
'application/x-www-form-urlencoded; charset=utf-8'
Я загрузил проект на GitHub, вы можете скачать и попробовать его.
Не стесняйтесь использовать функцию ниже:
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 ядро вы можете запросить токен напрямую,как документально:
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf @functions{ public string GetAntiXsrfRequestToken() { return Xsrf.GetAndStoreTokens(Context).RequestToken; } }
и использовать его в JavaScript:
function DoSomething(id) { $.post("/something/todo/"+id, { "__RequestVerificationToken": '@GetAntiXsrfRequestToken()' }); }
вы можете добавить рекомендуемый глобальный фильтр,как документально:
services.AddMvc(options => { options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()); })