Ajax post ASP.NET MVC에 antiforgerytoken 포함
AntiForgeryToken에 아약스 문제가 있습니다. 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.
속성을 다시 넣으면 메시지가 계속 나타납니다.
어떤 아이디어?
편집하다
위조 방지 토큰이 양식 내부에서 생성되고 있지만 제출 조치를 사용하여 제출하지 않습니다. 대신 jquery를 사용하여 토큰의 가치를 얻은 다음 아약스를 게시하려고합니다.
토큰을 포함하고 맨 위 마스터 페이지에있는 양식은 다음과 같습니다.
<form id="__AjaxAntiForgeryForm" action="#" method="post">
@Html.AntiForgeryToken()
</form>
에를 잘못 지정 contentType
했습니다 application/json
.
이것이 어떻게 작동하는지에 대한 예는 다음과 같습니다.
제어 장치:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(string someValue)
{
return Json(new { someValue = someValue });
}
}
전망:
@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>
내가 한 또 다른 (자바 스크립트) 접근 방식은 다음과 같습니다.
먼저 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));
}
문자열을 반환합니다
__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({
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]
Asp.Net Core에서는 다음과 같이 문서화 된대로 토큰을 직접 요청할 수 있습니다 .
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
public string GetAntiXsrfRequestToken()
{
return Xsrf.GetAndStoreTokens(Context).RequestToken;
}
}
그리고 자바 스크립트에서 사용하십시오 :
function DoSomething(id) {
$.post("/something/todo/"+id,
{ "__RequestVerificationToken": '@GetAntiXsrfRequestToken()' });
}
다음과 같이 권장되는 전역 필터를 추가 할 수 있습니다 .
services.AddMvc(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
})
DeletePersonel (id) {함수 var data = new FormData (); data.append ( "__ RequestVerificationToken", "@ HtmlHelper.GetAntiForgeryToken ()"); $ .ajax ({ 유형 : 'POST', url : '/ Personel / Delete /'+ id, 데이터 : 데이터, 캐시 : false, processData : false, contentType : false, 성공 : 기능 (결과) { } }); } 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 ""; } }
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
I know this is an old question. But I will add my answer anyway, might help someone like me.
If you dont want to process the result from the controller's post action, like calling the LoggOff
method of Accounts
controller, you could do as the following version of @DarinDimitrov 's answer:
@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>
I tried a lot of workarrounds and non of them worked for me. The exception was "The required anti-forgery form field "__RequestVerificationToken" .
What helped me out was to switch form .ajax to .post:
$.post(
url,
$(formId).serialize(),
function (data) {
$(formId).html(data);
});
Feel free to use the function below:
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 Account controller:
// POST: /Account/SendVerificationCodeSMS
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public JsonResult SendVerificationCodeSMS(string PhoneNumber)
{
return Json(PhoneNumber);
}
In View:
$.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);
}
});
It is important to set contentType
to 'application/x-www-form-urlencoded; charset=utf-8'
or just omit contentType
from the object ...
The token won't work if it was supplied by a different controller. E.g. it won't work if the view was returned by the Accounts
controller, but you POST
to the Clients
controller.
참고URL : https://stackoverflow.com/questions/14473597/include-antiforgerytoken-in-ajax-post-asp-net-mvc
'Programing' 카테고리의 다른 글
jQuery는 div 태그 안에 이미지를 추가합니다. (0) | 2020.06.12 |
---|---|
정적 라이브러리의 Objective-C 범주 (0) | 2020.06.12 |
문자열에서 줄 바꿈 문자를 제거하는 방법은 무엇입니까? (0) | 2020.06.12 |
Eclipse에서 사용하지 않는 가져 오기를 제거하는 방법 (0) | 2020.06.12 |
Netbeans 7 또는 8의 어두운 테마 (0) | 2020.06.12 |