programing

양식에 대한 AJAX 포스트 요청에서 CSRF 토큰을 전달하는 방법은?

stoneblock 2023. 10. 21. 09:54

양식에 대한 AJAX 포스트 요청에서 CSRF 토큰을 전달하는 방법은?

Scala Play! 2.6 Framework를 사용하고 있지만 문제가 되지 않을 수 있습니다.저는 그들의 자바스크립트 라우팅을 사용하고 있습니다. 그리고 그것은 정상적으로 작동하는 것처럼 보이지만 문제가 있습니다.렌더링 시 CSRF 토큰이 포함된 양식이 있습니다.

<form method="post" id="myForm" action="someURL">

<input name="csrfToken" value="5965f0d244b7d32b334eff840...etc" type="hidden">
  <input type="text" id="sometext">
  <button type="submit"> Submit! </button>

</form>

그리고 대략 여기, 나의 AJAX:

$(document).on('submit', '#myForm', function (event) {

 event.preventDefault();
   var data = {
    textvalue: $('#sometext').val()
   }
 var route = jsRoutes.controllers.DashboardController.postNewProject()
 $.ajax({
    url: route.url,
    type: route.type,
    data : JSON.stringify(data),
    contentType : 'application/json',
    success: function (data) { ...      },
    error: function (data) { ...  }
        })

});

그러나 이 글을 올리자 서버에서 무단 응답이 반환되고 IntelliJ의 콘솔에서 CSRF 검사가 실패하고 있다는 메시지가 나타납니다.요청 시 CSRF 토큰을 어떻게 전달해야 합니까?

좋아요, 몇 시간 동안 이것과 싸우고 플레이의 자주 부족한 문맥의 문서를 해독하려고 노력한 후에, 제가 이해했습니다.

그럼, 문서에서:

브라우저 이외의 요청에 대한 간단한 보호를 허용하기 위해 재생은 헤더에 쿠키가 있는 요청만 확인합니다.AJAX를 사용하여 요청을 하는 경우, HTML 페이지에 CSRF 토큰을 배치한 후, 해당 토큰을 사용하여 요청에 추가할 수 있습니다.Csrf-Token머리말

그리고 코드나 예시가 없습니다.Thanks Play.설명력이 뛰어나네요.어쨌든, 다음은 다음과 같습니다.

당신의view.html.formTemplateIntelliJ로 다음과 같이 적을 수 있습니다.

@()
<form method="post" id="myForm" action="someURL">

@helper.CSRF.formField  <!-- This auto-generates a token for you -->
  <input type="text" id="sometext">
  <button type="submit"> Submit! </button>

</form>

그리고 이는 고객에게 전달될 때 다음과 같이 렌더링됩니다.

<form method="post" id="myForm" action="someURL">

<input name="csrfToken" value="5965f0d244b7d32b334eff840...etc" type="hidden">
  <input type="text" id="sometext">
  <button type="submit"> Submit! </button>

</form>

좋아요, 거의 다 왔어요, 이제 AJAX 콜을 만들어야 해요.나는 내 모든 것을 별도의 main.js 파일에 가지고 있지만, 이것을 당신의 파일에 넣을 수도 있습니다.view.html.formTemplate네가 원한다면.

$(document).on('submit', '#myForm', function (event) {

 event.preventDefault();
   var data = {
    myTextToPass: $('#sometext').val()
   }
 // LOOK AT ME! BETWEEN HERE AND
 var token =  $('input[name="csrfToken"]').attr('value')
    $.ajaxSetup({
        beforeSend: function(xhr) {
            xhr.setRequestHeader('Csrf-Token', token);
        }
    });
// HERE
 var route = jsRoutes.controllers.DashboardController.postNewProject()
 $.ajax({
    url: route.url,
    type: route.type,
    data : JSON.stringify(data),
    contentType : 'application/json',
    success: function (data) { ...      },
    error: function (data) { ...  }
        })

});

다음 줄 사용:var token = $('input[name="csrfToken"]').attr('value')폼 필드에서 자동으로 생성된 CSRF 토큰을 뽑아내고 자바스크립트에서 사용할 var에서 값을 잡고 있습니다.

AJAX의 또 다른 중요한 부분은 다음과 같습니다.

$.ajaxSetup({
            beforeSend: function(xhr) {
                xhr.setRequestHeader('Csrf-Token', token);
            }
        });

으로.$.ajaxSetup, 머리글에 있는 것을 설정할 수 있습니다.이것은 그들의 문서에서 추론해야 할 것입니다.

Crf-Token 헤더를 사용하여 요청에 추가합니다.

행운을 빕니다.이것이 확실하면 저에게 알려주십시오.


참고: lusca를 사용할 때 사용합니다.X-CSRF-Token대신에Csrf-Token.

JSP발

<form method="post" id="myForm" action="someURL">
    <input name="csrfToken" value="5965f0d244b7d32b334eff840...etc" type="hidden">    
</form>

이것이 3시간 동안 고생한 나에게 가장 간단한 방법입니다. 이렇게 입력 히든 필드에서 토큰을 가져와 AJAX 요청을 하면서 다음과 같이 헤더에 토큰을 전달하기만 하면 됩니다:-

JQuery에서

var token =  $('input[name="csrfToken"]').attr('value'); 

일반 자바스크립트에서

var token = document.getElementsByName("csrfToken").value;

최종 AJAX 요청

$.ajax({
          url: route.url,
          data : JSON.stringify(data),
          method : 'POST',
          headers: {
                        'X-CSRFToken': token 
                   },
          success: function (data) { ...      },
          error: function (data) { ...  }
});

이제 웹 구성에서 crsf 보안을 비활성화할 필요가 없으며 콘솔에서 405(Method Not Allowed) 오류도 발생하지 않습니다.

이것이 사람들에게 도움이 되기를 바랍니다.!!

를 사용하여 요청에 추가합니다.Csrf-Token머리말

헤더 이름을 알려주신 Nate H06님께 감사드립니다!아약스 함수 호출이 있는 "삭제" 버튼을 위해 crf 토큰을 보내려다가 다음과 같이 막혔습니다.

@import helper._
....
<button id="deleteBookBtn" class="btn btn-danger"
        data-csrf-name="@helper.CSRF.getToken.name"
        data-csrf-value="@helper.CSRF.getToken.value"
        data-delete-url="@routes.BooksController.destroy(book.id)"
        data-redirect-url="@routes.HomeController.index()">Delete</button>

온라인 js를 추가하지 못했습니다.onclick()2.6 플레이에 CSP 세트로 인해 이벤트도 발생합니다.

인라인 이벤트 처리기가 컨텐츠 보안 정책 지침인 "default-src 'self'"를 위반하므로 실행을 거부했습니다.

그리고 JS 파일에:

function sendDeleteRequest(event) {
  url = event.target.getAttribute("data-delete-url")
  redirect = event.target.getAttribute("data-redirect-url")
  csrfTokenName = event.target.getAttribute("data-csrf-name")
  csrfTokenValue = event.target.getAttribute("data-csrf-value")
  $.ajax({
    url: url,
    method: "DELETE",
    beforeSend: function(request) {
      //'Csrf-Token' is the expected header name, not $csrfTokenName
      request.setRequestHeader(/*$csrfTokenName*/'Csrf-Token', csrfTokenValue);
    },
    success: function() {
      window.location = redirect;
    },
    error: function() {
      window.location.reload();
    }
  })
}

var deleteBookBtn = document.getElementById("deleteBookBtn");
if(deleteBookBtn) {
    deleteBookBtn.addEventListener("click", sendDeleteRequest);
}

머리글 이름을 다음과 같이 설정한 후'Csrf-Token'아약스 콜이 완벽하게 작동합니다!

구글 검색을 통해 정확한 토큰이 나타나지 않는 이유를 파악하는 다른 사용자에게 유용한 경우.재생 백엔드/반응 프론트엔드 조합에 대해 동일한 문제로 어려움을 겪고 있습니다. 그래서 토큰 in html 페이지 기법을 사용할 수 없게 되었습니다. 결국 쿠키에 현재 토큰을 설정하는 다른 솔루션을 발견했습니다. 간단히 다음을 추가하십시오.

play.filters.csrf {
  cookie.name = "csrftoken"
}

application.conf 및 the.에csrftokencookie가 토큰으로 설정됩니다.그런 다음 https://www.npmjs.com/package/js-cookie 을 사용하여 JS 코드에 있는 값을 잡고 요청 헤더에 다시 보냈습니다. OP에 대해서는 jQuery가 아닌 React이기 때문에 문제를 혼동하고 싶지 않기 때문에 여기에 코드를 포함하지 않았습니다.

추가할 수 있습니다.Csrf-Token머리글로 붙이기headers선택.

$.ajax({
    url: '@routes.MyController.myPostAction()',
    method: 'post',
    headers: {
        'Csrf-Token': '@play.filters.csrf.CSRF.getToken.map(_.value)'
    },
    data: {
        name: '@name'
    },
    success: function (data, textStatus, jqXHR) {
        location.reload();
    },
    error: function (jqXHR, textStatus, errorThrown) {
        debugger;
    }
});

Play Framework 2.6 Documentation에 명시되어 있는 것처럼 '를 설정할 수 있습니다.Csrf-Token' Play에서 생성된 토큰으로 머리글:

AJAX를 사용하여 요청을 하는 경우, HTML 페이지에 CSRF 토큰을 배치한 후, 해당 토큰을 사용하여 요청에 추가할 수 있습니다.Csrf-Token머리말

Scala-Template 내에서 다음을 사용하여 토큰 값을 얻을 수 있습니다.@helper.CSRF.getToken.value

jQuery Documentation에 따라 jaxSetup을 사용하여 jQuery를 구성하여 모든 Ajax 요청에 대해 한 번 설정할 수 있습니다.

$.ajaxSetup({
  beforeSend: function(xhr) {
    xhr.setRequestHeader('Csrf-Token', '@helper.CSRF.getToken.value');
  }
});

또는 모든 요청에 대해 헤더를 설정할 수 있습니다.headers다음과 같은 개체:

$.ajax({
  url: route.url,
  ...
  headers: {
    'Csrf-Token': '@helper.CSRF.getToken.value'
  }
});

slim crf gurd, jQuery에서 crf 키와 토큰을 전달하는 방법 twig와 함께 slim application을 위한 방법

$(document).ready(function(){
    $.ajaxPrefilter(function(options, originalOptions, jqXHR){

        var allowedMethod = ["post", "put", "delete"];

        if (allowedMethod.includes(options.type.toLowerCase())  ) {
            // initialize `data` to empty string if it does not exist
            options.data = options.data || "";

            // add leading ampersand if `data` is non-empty
            options.data += options.data?"&":"";

            // add _token entry
            options.data += "{{csrf.keys.name}}={{csrf.name}}&{{csrf.keys.value}}={{csrf.value}}";
        }
    });
});

언급URL : https://stackoverflow.com/questions/45470802/how-to-pass-along-csrf-token-in-an-ajax-post-request-for-a-form