включить 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()); })