include antiforgerytoken in ajax post ASP.NET MVC

Mam problem z Antyforgerytoken z Ajaxem. Używam ASP.NET MVC 3. Wypróbowałem rozwiązanie w wywołaniach jQuery Ajax i Html.AntiForgeryToken () . Przy użyciu tego rozwiązania token jest teraz przekazywany:

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) {
            ...
        }
    });

Kiedy usuwam atrybut [ValidateAntiForgeryToken] tylko po to, aby sprawdzić, czy dane (z tokenem) są przekazywane jako parametry do kontrolera, widzę, że są przekazywane. Ale z jakiegoś powodu, wiadomość A required anti-forgery token was not supplied or was invalid. nadal wyskakuje, gdy umieszczam atrybut do tyłu.

Jakieś pomysły?

EDIT

Antyforgerytoken jest generowany wewnątrz formularza, ale nie używam akcji submit, aby go przesłać. Zamiast tego, po prostu się wartość tokena za pomocą jquery, a następnie próbuje Ajax post, że.

Oto formularz, który zawiera token i znajduje się na górnej stronie wzorca:

<form id="__AjaxAntiForgeryForm" action="#" method="post">
    @Html.AntiForgeryToken()
</form>
Author: Community, 2013-01-23

9 answers

Błędnie podałeś contentType do application/json.

Oto przykład, jak to może działać.

Kontroler:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Index(string someValue)
    {
        return Json(new { someValue = someValue });
    }
}

Widok:

@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>
 223
Author: Darin Dimitrov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-23 06:54:03

Inne (mniej javascriptowe) podejście, które zrobiłem, idzie mniej więcej tak:

Najpierw 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));
}

Który zwróci łańcuch

__RequestVerificationToken:"P5g2D8vRyE3aBn7qQKfVVVAsQc853s-naENvpUAPZLipuw0pa_ffBf9cINzFgIRPwsf7Ykjt46ttJy5ox5r3mzpqvmgNYdnKc1125jphQV0NnM5nGFtcXXqoY3RpusTH_WcHPzH4S4l1PmB8Uu7ubZBftqFdxCLC5n-xT0fHcAY1"

Więc możemy go używać w ten sposób

$(function () {
    $("#submit-list").click(function () {
        $.ajax({
            url: '@Url.Action("SortDataSourceLibraries")',
            data: { items: $(".sortable").sortable('toArray'), @Html.AntiForgeryTokenForAjaxPost() },
            type: 'post',
            traditional: true
        });
    });
});

I wydaje się działać!

 51
Author: Max Wikström,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-17 10:23:28

To takie proste! gdy używasz @Html.AntiForgeryToken() w kodzie html, oznacza to, że serwer podpisał tę stronę, a każde żądanie wysyłane do serwera z tej konkretnej strony ma znak, który uniemożliwia wysłanie fałszywego żądania przez hakerów. aby ta strona została uwierzytelniona przez serwer należy przejść przez dwa kroki:

1.wyślij parametr o nazwie __RequestVerificationToken i aby otrzymać jego wartość użyj kodów poniżej:

<script type="text/javascript">
    function gettoken() {
        var token = '@Html.AntiForgeryToken()';
        token = $(token).val();
        return token;
   }
</script>

Na przykład weź wywołanie 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,
});

I krok 2 po prostu udekoruj swój metoda działania przez [ValidateAntiForgeryToken]

 32
Author: Abolfazl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-16 15:35:39


        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 "";
            }
        }
 4
Author: ismail eski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-01 18:41:46

Wiem, że to stare pytanie. Ale i tak dodam swoją odpowiedź, może ktoś taki jak ja pomoże.

Jeśli nie chcesz przetwarzać wyniku działania post kontrolera, np. wywołania metody LoggOff kontrolera Accounts, możesz wykonać następującą wersję odpowiedzi @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>
 2
Author: Aamir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-27 21:22:40

Próbowałem wiele pracy i żaden z nich nie pracował dla mnie. Wyjątkiem było "wymagane pole formularza anty-forgery "__RequestVerificationToken".

Pomogło mi to zmienić formę .ajax do .post:
$.post(
    url,
    $(formId).serialize(),
    function (data) {
        $(formId).html(data);
    });
 0
Author: Stefan Michev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-19 15:06:19

W Asp.Net MVC gdy używasz @Html.AntiForgeryToken() Razor tworzy ukryte pole wejściowe o nazwie __RequestVerificationToken do przechowywania tokenów. Jeśli chcesz napisać implementację AJAX, musisz pobrać ten token i przekazać go jako parametr do serwera, aby mógł zostać zweryfikowany.

Krok 1: Pobierz token

var token = $('input[name="`__RequestVerificationToken`"]').val();
Aby uzyskać więcej informacji, skontaktuj się z nami.]}
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')
      }
})
};

Uwaga : typem zawartości powinno być 'application/x-www-form-urlencoded; charset=utf-8'

Załadowałem projekt na Github; możesz pobrać i spróbować to.

Https://github.com/lambda2016/AjaxValidateAntiForgeryToken

 0
Author: Frank Odoom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-20 19:16:49

Zapraszam do korzystania z funkcji poniżej:

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
    }
});

}

 0
Author: Komal Narang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-19 16:36:41

W Asp.Net Core możesz zażądać tokena bezpośrednio, zgodnie z dokumentacją :

@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf    
@functions{
    public string GetAntiXsrfRequestToken()
    {
        return Xsrf.GetAndStoreTokens(Context).RequestToken;
    }
}

I użyj go w javascript:

function DoSomething(id) {
    $.post("/something/todo/"+id,
               { "__RequestVerificationToken": '@GetAntiXsrfRequestToken()' });
}

Możesz dodać zalecany filtr globalny, zgodnie z dokumentacją :

services.AddMvc(options =>
{
    options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
})
 0
Author: Ruard van Elburg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-04 15:44:07