include antiforgerytoken in ajax post ASP.NET MVC

ID : 20366

viewed : 14

Tags : asp.netajaxasp.net-mvcasp.net-mvc-3csrfasp.net

Top 5 Answer for include antiforgerytoken in ajax post ASP.NET MVC

vote vote

100

You have incorrectly specified the contentType to application/json.

Here's an example of how this might work.

Controller:

public class HomeController : Controller {     public ActionResult Index()     {         return View();     }      [HttpPost]     [ValidateAntiForgeryToken]     public ActionResult Index(string someValue)     {         return Json(new { someValue = someValue });     } } 

View:

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

88

Another (less javascriptish) approach, that I did, goes something like this:

First, an 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)); } 

that will return a string

__RequestVerificationToken:"P5g2D8vRyE3aBn7qQKfVVVAsQc853s-naENvpUAPZLipuw0pa_ffBf9cINzFgIRPwsf7Ykjt46ttJy5ox5r3mzpqvmgNYdnKc1125jphQV0NnM5nGFtcXXqoY3RpusTH_WcHPzH4S4l1PmB8Uu7ubZBftqFdxCLC5n-xT0fHcAY1" 

so we can use it like this

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

And it seems to work!

vote vote

79

it is so simple! when you use @Html.AntiForgeryToken() in your html code it means that server has signed this page and each request that is sent to server from this particular page has a sign that is prevented to send a fake request by hackers. so for this page to be authenticated by the server you should go through two steps:

1.send a parameter named __RequestVerificationToken and to gets its value use codes below:

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

for example take an ajax call

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

and step 2 just decorate your action method by [ValidateAntiForgeryToken]

vote vote

67

In Asp.Net Core you can request the token directly, as documented:

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

And use it in javascript:

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

You can add the recommended global filter, as documented:

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

Update

The above solution works in scripts that are part of the .cshtml. If this is not the case then you can't use this directly. My solution was to use a hidden field to store the value first.

My workaround, still using GetAntiXsrfRequestToken:

When there is no form:

<input type="hidden" id="RequestVerificationToken" value="@GetAntiXsrfRequestToken()"> 

The name attribute can be omitted since I use the id attribute.

Each form includes this token. So instead of adding yet another copy of the same token in a hidden field, you can also search for an existing field by name. Please note: there can be multiple forms inside a document, so name is in that case not unique. Unlike an id attribute that should be unique.

In the script, find by id:

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

An alternative, without having to reference the token, is to submit the form with script.

Sample form:

<form id="my_form" action="/something/todo/create" method="post"> </form> 

The token is automatically added to the form as a hidden field:

<form id="my_form" action="/something/todo/create" method="post"> <input name="__RequestVerificationToken" type="hidden" value="Cf..." /></form> 

And submit in the script:

function DoSomething() {     $('#my_form').submit(); } 

Or using a post method:

function DoSomething() {     var form = $('#my_form');      $.post("/something/todo/create", form.serialize()); } 
vote vote

58

In Asp.Net MVC when you use @Html.AntiForgeryToken() Razor creates a hidden input field with name __RequestVerificationToken to store tokens. If you want to write an AJAX implementation you have to fetch this token yourself and pass it as a parameter to the server so it can be validated.

Step 1: Get the token

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

Step 2: Pass the token in the AJAX call

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: The content type should be 'application/x-www-form-urlencoded; charset=utf-8'

I have uploaded the project on Github; you can download and try it.

https://github.com/lambda2016/AjaxValidateAntiForgeryToken

Top 3 video Explaining include antiforgerytoken in ajax post ASP.NET MVC

Related QUESTION?