it-swarm.com.de

antiforgerytoken in ajax post ASP.NET MVC enthalten

Ich habe Probleme mit dem AntiForgeryToken mit Ajax. Ich verwende ASP.NET MVC 3. Ich habe die Lösung in jQuery Ajax-Aufrufen und dem Html.AntiForgeryToken () versucht. Mit dieser Lösung wird das Token nun übergeben:

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

Wenn ich das [ValidateAntiForgeryToken]-Attribut entferne, nur um zu sehen, ob die Daten (mit dem Token) als Parameter an den Controller übergeben werden, kann ich sehen, dass sie übergeben werden. Aber aus irgendeinem Grund wird die A required anti-forgery token was not supplied or was invalid.-Nachricht immer noch angezeigt, wenn ich das Attribut zurücksetze.

Irgendwelche Ideen?

EDIT

Das Antiforgerytoken wird in einem Formular generiert, aber ich übermittle es nicht mit einer Submit-Aktion. Stattdessen bekomme ich nur den Wert des Tokens, indem ich jquery verwende und dann versuche, das zu posten.

Hier ist das Formular, das das Token enthält und sich auf der obersten Masterseite befindet:

<form id="__AjaxAntiForgeryForm" action="#" method="post">
    @Html.AntiForgeryToken()
</form>
129
OJ Raqueño

Sie haben die contentType falsch in application/json angegeben. 

Hier ist ein Beispiel, wie das funktionieren könnte.

Regler:

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

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

Aussicht:

@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>
235
Darin Dimitrov

Ein anderer (weniger Javascript) -Ansatz, den ich gemacht habe, geht in etwa so

Zuerst ein Html-Helfer

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

das wird eine Zeichenfolge zurückgeben

__RequestVerificationToken:"P5g2D8vRyE3aBn7qQKfVVVAsQc853s-naENvpUAPZLipuw0pa_ffBf9cINzFgIRPwsf7Ykjt46ttJy5ox5r3mzpqvmgNYdnKc1125jphQV0NnM5nGFtcXXqoY3RpusTH_WcHPzH4S4l1PmB8Uu7ubZBftqFdxCLC5n-xT0fHcAY1"

so können wir es so verwenden

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

Und es scheint zu funktionieren!

55
Max Wikstrom

es ist so einfach! Wenn Sie @Html.AntiForgeryToken() in Ihrem HTML-Code verwenden, bedeutet dies, dass der Server diese Seite signiert hat und jede Anforderung, die von dieser bestimmten Seite an den Server gesendet wird, ein Zeichen enthält, das verhindert, dass Hacker eine gefälschte Anforderung senden. Damit diese Seite vom Server authentifiziert werden kann, müssen Sie zwei Schritte ausführen:

1.Senden Sie einen Parameter mit dem Namen __RequestVerificationToken und erhalten Sie den folgenden Wert für die Verwendung von Codes:

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

nehmen Sie zum Beispiel einen Ajax-Anruf

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

und Schritt 2 schmücken Sie einfach Ihre Aktionsmethode mit [ValidateAntiForgeryToken]

35
Abolfazl

 Funktion DeletePersonel (id) {

 var data = new FormData (); 
 data.append ("__ RequestVerificationToken", "@ HtmlHelper.GetAntiForgeryToken ()"); 

 $ .ajax ({
 Typ: 'POST', 
 URL: '/ Personel/Delete /' + ID, 
 Daten: Daten, 
 Cache: falsch, 
 Prozessdaten: Falsch, 
 contentType: false, 
 success: Funktion (Ergebnis) {

} 
}); 

 } 
 

 öffentliche statische Klasse HtmlHelper 
 {
 öffentliche statische Zeichenfolge GetAntiForgeryToken () 
 {
 System.Text.RegularExpressions.Match value = System.Text.RegularExpressions.Regex.Match (System.Web.Helpers.AntiForgery.GetHtml (). ToString (), "(?: Value = \") (. *) (?). :\")"); 
 if (value.Success) 
 {
 Rückgabewert.Gruppen [1] .Value; 
 } 
 Rückkehr "";
 } 
 } 
5
ismail eski

In Asp.Net Core können Sie das Token direkt anfordern, wie dokumentiert :

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

Und benutze es in Javascript:

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

Sie können den empfohlenen globalen Filter hinzufügen wie dokumentiert :

services.AddMvc(options =>
{
    options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
})
4

Wenn Sie in Asp.Net MVC @Html.AntiForgeryToken() verwenden, erstellt Razor ein verstecktes Eingabefeld mit dem Namen __RequestVerificationToken zum Speichern von Token. Wenn Sie eine AJAX -Implementierung schreiben möchten, müssen Sie dieses Token selbst abrufen und als Parameter an den Server übergeben, damit es überprüft werden kann.

Schritt 1: Holen Sie sich das Token

var token = $('input[name="`__RequestVerificationToken`"]').val();

Schritt 2: Übergeben Sie das Token beim Aufruf von 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: Der Inhaltstyp sollte 'application/x-www-form-urlencoded; charset=utf-8' sein.

Ich habe das Projekt auf Github hochgeladen. Sie können es herunterladen und ausprobieren.

https://github.com/lambda2016/AjaxValidateAntiForgeryToken

2
Frank Odoom

Ich weiß, das ist eine alte Frage. Aber ich werde meine Antwort trotzdem hinzufügen, könnte jemandem wie mir helfen. 

Wenn Sie das Ergebnis der Nachaktion des Controllers nicht verarbeiten möchten, z. B. das Aufrufen der LoggOff-Methode des Accounts-Controllers, können Sie die folgende Version der Antwort von @DarinDimitrov ausführen:

@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
Aamir

Ich habe viele Workarounds ausprobiert und keiner von ihnen hat für mich gearbeitet. Die Ausnahme war "Das erforderliche Anti-Fälschungs-Formularfeld" __RequestVerificationToken ". 

Was mir geholfen hat, war, von .ajax zu .post zu wechseln: 

$.post(
    url,
    $(formId).serialize(),
    function (data) {
        $(formId).html(data);
    });
0
Stefan Michev

Das Token funktioniert nicht, wenn es von einem anderen Controller geliefert wurde. Z.B. Es funktioniert nicht, wenn die Ansicht vom Controller Accounts zurückgegeben wurde, aber Sie POST zum Controller Clients.

0
OutstandingBill

In Account Controller:

    // POST: /Account/SendVerificationCodeSMS
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public JsonResult SendVerificationCodeSMS(string PhoneNumber)
    {
        return Json(PhoneNumber);
    }

Im Hinblick auf:

$.ajax(
{
    url: "/Account/SendVerificationCodeSMS",
    method: "POST",
    contentType: 'application/x-www-form-urlencoded; charset=utf-8',
    dataType: "json",
    data: {
        PhoneNumber: $('[name="PhoneNumber"]').val(),
        __RequestVerificationToken: $('[name="__RequestVerificationToken"]').val()
    },
    success: function (data, textStatus, jqXHR) {
        if (textStatus == "success") {
            alert(data);
            // Do something on page
        }
        else {
            // Do something on page
        }
    },
    error: function (jqXHR, textStatus, errorThrown) {
        console.log(textStatus);
        console.log(jqXHR.status);
        console.log(jqXHR.statusText);
        console.log(jqXHR.responseText);
    }
});

Es ist wichtig, contentType auf 'application/x-www-form-urlencoded; charset=utf-8' zu setzen oder einfach contentTypevon dem Objekt wegzulassen ...

0
Adel Mourad

Fühlen Sie sich frei, die folgende Funktion zu verwenden:

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
Komal Narang