programing

위조 방지 토큰을 사용하여 Ajax 요청을 만드는 방법(mvc)

elecom 2023. 8. 16. 21:57
반응형

위조 방지 토큰을 사용하여 Ajax 요청을 만드는 방법(mvc)

저는 MVC 프로젝트의 아래 세부 사항에 문제가 있습니다.

회전 gif(또는 심지어 텍스트)와 같은 로딩 패널과 함께 jquery agax 요청을 사용하려고 하면 fiddler에서 관찰되는 오류가 발생합니다.

필수 위조 방지 양식 필드 "__RequestVerification"토큰"이 없습니다.

댓글 달면[ValidateAntiForgeryToken] attributePOST 조치 방법 및 로딩 패널을 사용하면 정상적으로 작동합니다.이 오류가 발생하는 이유를 알고 싶습니다.

쿼리 문자열을 사용한 적도 있습니다.

__RequestVerificationToken= $('input[name="__RequestVerificationToken"').val()

여전히 오류가 발생하고 있습니다.

위조 방지 토큰의 암호를 해독할 수 없습니다.이 응용 프로그램이 웹 팜 또는 클러스터에서 호스트되는 경우 모든 컴퓨터에서 동일한 버전의 ASP를 실행하고 있는지 확인합니다.NET 웹 페이지 및 기타<machineKey>구성은 명시적 암호화 및 유효성 검사 키를 지정합니다.

클러스터에서 자동 생성을 사용할 수 없습니다.

무엇을 사용해야 합니까?

여기서 질문 코드를 업데이트했습니다.

var token = $('input[name="__RequestVerificationToken"]').val();
$('#submitaddress').click(function subaddr(event) {
    event.preventDefault();
    event.stopPropagation();
  //$('#addAddress').html('<img src="/img/animated-overlay.gif"> Sending...');
   // $('#addAddress').blur();
    //  $(this).bl
    if ($('#Jobid').val()!="") {
        $('#TransportJobId').val(parseInt($('#Jobid').val()));
        $.ajax(
              {
                  url: '/TransportJobAddress/create',
                  type: 'POST',
                  data: "__RequestVerificationToken=" + token + "" + $('form[action="/TransportJobAddress/Create"]').serialize(),
                  success: function poste(data, textStatus, jqXHR) { $('#addAddress').html(data); return false; },
                  error: function err(jqXHR, textStatus, errorThrown) { alert('error at address :' + errorThrown); }
              });
    }
    else {
        var transportid = 2;
        $.ajax({
            url: '/TransportJob/create',
            type: 'POST',
            data: "__RequestVerificationToken=" + token + "" + $('form[action="/TransportJob/Create"]').serialize(),
            success: function sfn(data, textStatus, jqXHR) {
                transportid = parseInt(data);
                $('#Jobid').val(data);
               // alert('inserted id :' + data);
                $('#TransportJobId').val((transportid));
                $.ajax(
         {

             url: '/TransportJobAddress/create',
             type: 'POST',
             //beforeSend: function myintserver(xhr){  
             //        $('#addAddress').html('<div id="temp_load" style="text-align:center">please wait ...</div>');
             //}, 
             data: "__RequestVerificationToken=" + token + "" + $('form[action="/TransportJobAddress/Create"]').serialize(),
             success: function poste(data, textStatus, jqXHR) {
                 $('#addAddress').html(data);

             },
             error: function err(jqXHR, textStatus, errorThrown) {
                 alert('error at address :' + errorThrown);
             }

         });
            },
            error: function myfunction(jqXHR, textStatus, errorThrown) {
                alert("error at transport :" + jqXHR.textStatus);
            },
            complete: function completefunc() {
              //  alert('ajax completed all requests');
                return false;
            }

        });
    }
});

양식 태그

<form action="/TransportJob/Create" method="post"><input     name="__RequestVerificationToken" type="hidden"   value="ydYSei0_RfyBf619dQrhDwwoCM7OwWkJQQEMNvNdAkefiFfYvRQ0MJYYu0zkktNxlJk_y1ZJO9-yb-  COap8mqd0cvh8cDYYik4HJ0pZXTgE1" />   

동일한 페이지의 TransportJob 양식 태그 2

<form action="/TransportJobAddress/Create" method="post" novalidate="novalidate"><input name="__RequestVerificationToken" type="hidden"    value="Np2vUZJPk1TJlv846oPSU6hg4SjMHRcCk1CacaqZbpHOg8WbV4GZv06noRDl7F_iT9qQf3BIXo3n9wGW68sU mki7g3-ku_BSHBDN-g2aaKc1"> 

각 요청에 수동으로 추가하는 것이 아니라 주로 다음과 같은 작업을 수행합니다.

var token = $('input[name="__RequestVerificationToken"]').val();
$.ajaxPrefilter(function (options, originalOptions) {
  if (options.type.toUpperCase() == "POST") {
    options.data = $.param($.extend(originalOptions.data, { __RequestVerificationToken: token }));
  }
});

그러면 토큰이 자동으로 모든 Ajax POST에 추가됩니다.

아약스 호출의 헤더에 토큰을 추가했습니까?

위조 방지 기능을 추가해야 합니다.Ajax 호출의 메시지 헤더에 있는 토큰:

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

var headers = {};

headers['__RequestVerificationToken'] = token;

$.ajax({
        url: ... some url,
        headers: headers,
        ....
});

코드로 시도해 보십시오.

var token = $('input[name="__RequestVerificationToken"]').val();
var tokenadr = $('form[action="/TransportJobAddress/Create"] input[name="__RequestVerificationToken"]').val(); 

var headers = {};
var headersadr = {};
headers['__RequestVerificationToken'] = token;
headersadr['__RequestVerificationToken'] = tokenadr;

$('#submitaddress').click(function subaddr(event) {
    event.preventDefault();
    event.stopPropagation();
  //$('#addAddress').html('<img src="/img/animated-overlay.gif"> Sending...');
   // $('#addAddress').blur();
    //  $(this).bl
    if ($('#Jobid').val()!="") {
        $('#TransportJobId').val(parseInt($('#Jobid').val()));
        $.ajax(
              {
                  url: '/TransportJobAddress/create',
                  type: 'POST',
                  headers:headersadr, 
                  data: "__RequestVerificationToken=" + token + "" + $('form[action="/TransportJobAddress/Create"]').serialize(),
                  success: function poste(data, textStatus, jqXHR) { $('#addAddress').html(data); return false; },
                  error: function err(jqXHR, textStatus, errorThrown) { alert('error at address :' + errorThrown); }
              });
    }
    else {
        var transportid = 2;
        $.ajax({
            url: '/TransportJob/create',
            type: 'POST',
            headers:headers, 
            data: $('form[action="/TransportJob/Create"]').serialize(),
            success: function sfn(data, textStatus, jqXHR) {
                transportid = parseInt(data);
                $('#Jobid').val(data);
               // alert('inserted id :' + data);
                $('#TransportJobId').val((transportid));
                $.ajax(
         {

             url: '/TransportJobAddress/create',
             type: 'POST',
             //beforeSend: function myintserver(xhr){  
             //        $('#addAddress').html('<div id="temp_load" style="text-align:center">please wait ...</div>');
             //},
             headers:headers, 
             data: $('form[action="/TransportJobAddress/Create"]').serialize(),
             success: function poste(data, textStatus, jqXHR) {
                 $('#addAddress').html(data);

             },
             error: function err(jqXHR, textStatus, errorThrown) {
                 alert('error at address :' + errorThrown);
             }

         });
            },
            error: function myfunction(jqXHR, textStatus, errorThrown) {
                alert("error at transport :" + jqXHR.textStatus);
            },
            complete: function completefunc() {
              //  alert('ajax completed all requests');
                return false;
            }

        });
    }
});

Ajax 호출에 헤더 행이 추가되었습니다.

토큰을 보기에 추가했습니까?다음과 같이:

<form method="post" action="/my-controller/my-action">
    @Html.AntiForgeryToken()
</form>

게시물을 수신하는 컨트롤러가 위조 방지 토큰을 찾고 있으므로 보기의 양식에 해당 토큰을 추가해야 합니다.

편집:

먼저 json에서 데이터를 구축해 보십시오.

var formData = $('form[action="/TransportJobAddress/Create"]').serialize();
$.extend(formData, {'__RequestVerificationToken': token });

//and then in your ajax call:
$.ajax({
    //...
    data:formData
    //...
});

보기 또는 레이아웃:

< form id='_id' 메서드='POST'> @html. 위조 방지토큰(); </form>

Ajax 호출 함수:

var data={...};
var token=$('#_id').serializeObject();
var dataWithAntiforgeryToken = $.extend(data,token);

$.ajax(
{
....,
data: dataWithAntiforgeryToken;
}
)

저는 Ajax와 일반 요청을 모두 보호하고 싶었기 때문에 다음과 같이 결정했습니다.

먼저 haacked.com 의 훌륭한 블로그를 사용하여 설명한 대로 조건부 필터 공급자를 만들었습니다.

그런 다음 코드가 생각되는 블로그에서 설명한 대로 모든 클래스를 만들었습니다.

제 _레이아웃 페이지에서 블로그에 설명된 바와 같이 $.ajax Prefilter로 작품을 추가했습니다.이렇게 하면 모든 Ajax 콜백이 헤더를 통해 위조 방지 토큰을 전송할 수 있습니다.

이 코드를 global.asax / Application_Start에 추가했습니다.

(c, a) =>
                    (c.HttpContext.Request.IsAjaxRequest() &&
                     !string.Equals(c.HttpContext.Request.HttpMethod, "GET"))
                        ? new AjaxValidateAntiForgeryTokenAttribute()
                        : null,
(c, a) =>
                    (!c.HttpContext.Request.IsAjaxRequest() &&
                     string.Equals(c.HttpContext.Request.HttpMethod, "POST", StringComparison.OrdinalIgnoreCase))
                        ? new ValidateAntiForgeryTokenAttribute()
                        : null

기본적으로..GET가 아닌 모든 컨트롤러에 속성을 주입합니다.

그 후에 저는 제 모든 (극소수) 양식으로 가서 @Html을 추가해야 했습니다.위조 방지토큰().

모든 것이 효과가 있었다는 것을 증명하기 위해 위조 방지 장치 없이 형태로 물건을 압축하려고 합니다.토큰을 사용하여 예상된 예외를 가져옵니다.$.ajaxPrefilter를 제거하고 Ajax 요청을 생성하면 예상 예외가 수신됩니다.

언급URL : https://stackoverflow.com/questions/19788916/how-to-make-ajax-request-with-anti-forgery-token-in-mvc

반응형