source

ajax 요청에 crf 토큰을 추가하는 방법

manysource 2023. 10. 22. 20:10

ajax 요청에 crf 토큰을 추가하는 방법

ajax 요청에 crf를 추가하는데 문제가 있습니다.스프링부트/스프링 보안이 적용된 고객측의 타임리프를 사용하고 있습니다.spring security에서 crf-token이 없어 요청을 허용하지 않습니다.아약스의 코드는 여기 있습니다.

function bits(){
    var xhttp = new XMLHttpRequest();
    var selected = document.getElementById("product").value;
    xhttp.onreadystatechange = function(){
      if(xhttp.readyState==4 && xhttp.status==200){
        var result= JSON.parse(xhttp.responseText)
        var length = result.length;
        for(i=0; i<length; i++){

           console.log(result[k].spid);
        }
    }

};

 xhttp.open("POST", "http://localhost:8080/bids?q="+selected,  true);
 xhttp.send();

}

도움을 주시면 감사하겠습니다.

@Prakash Hari Sharma의 솔루션을 수정했고 나에게 맞는 다음 코드를 가지고 있었습니다.참고: Thymeleaf를 사용하는 경우 접두사.

--헤더 섹션

<meta th:name="_csrf" th:content="${_csrf.token}"/>
<meta th:name="_csrf_header" th:content="${_csrf.headerName}"/>

아약스 스크립트 함수

...
...
var token = $("meta[name='_csrf']").attr("content"); 
var header = $("meta[name='_csrf_header']").attr("content");
...
...
xhttp.open("POST", "http://localhost:8080/bids?q="+selected,  true);
xhttp.setRequestHeader(header, token);
xhttp.send();

이것이 누군가에게도 도움이 되길 바랍니다.

@Edwardos의 답변을 보완하기 위해 메타 태그를 에 추가한 후<head>요소:

타임리프:

<meta th:name="_csrf" th:content="${_csrf.token}"/>
<meta th:name="_csrf_header" th:content="${_csrf.headerName}"/>

JSP:

<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>

...Spring 문서에 제시된 작업을 수행하고 향후의 모든 이점을 활용하여csrf:

$(function () {
    var token = $("meta[name='_csrf']").attr("content");
    var header = $("meta[name='_csrf_header']").attr("content");
    $(document).ajaxSend(function (e, xhr, options) {
        xhr.setRequestHeader(header, token);
    });
});

또한 봄 문서에서는 보안상의 이유로 GET 요청에 crf 토큰을 사용하지 않는 것이 좋습니다.

"토큰 수신 요청 범위를 지정할 수 있는 기능은 CSRF 토큰이 제3자에게 유출되는 것을 방지하는 데 도움이 됩니다."

따라서 다음과 같은 방식으로 POST 요청에 대해서만 토큰을 전달하도록 필터링할 수 있습니다.

$(function() {
    var token = $("meta[name='_csrf']").attr("content");
    var header = $("meta[name='_csrf_header']").attr("content");
    $(document).ajaxSend(function(e, xhr, options) {
        if (options.type == "POST") {
            xhr.setRequestHeader(header, token);
        }
    });
});

의 메타태그.<head>요소는 이전 답변과 동일합니다.

<meta th:name="_csrf" th:content="${_csrf.token}"/>
<meta th:name="_csrf_header" th:content="${_csrf.headerName}"/>

jsp 메타 태그에 CSRF 토큰 저장

<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>

ajax 요청에 crf 토큰 값을 추가합니다.

var elementToken = document.querySelector('meta[property="_csrf"]');
var token = elementToken && elementToken.getAttribute("content");
var elementHeader = document.querySelector('meta[property="_csrf_header"]');
var header = elementHeader && elementHeader.getAttribute("content");
xhttp.open("POST", "http://localhost:8080/bids?q="+selected,  true);
xmlhttp.setRequestHeader(header, token);
xhttp.send();

아래에서 crf와 함께 ajax를 사용할 수 있는 나의 코드를 찾을 수 있습니다.저도 Spring Security를 사용합니다.

    // In your JSP meta tags
    <meta name="_csrf" content="${_csrf.token}"/>
    <!-- default header name is X-CSRF-TOKEN -->
    <meta name="_csrf_header" content="${_csrf.headerName}"/>

    // In your javascript
    // CSRF Variables
    var _tc = $("meta[name='_csrf']").attr("content");
    var _hc = $("meta[name='_csrf_header']").attr("content");


    // Header
    var headersStomp = {};
    headersStomp[_hc] = _tc;

    $(document).ajaxSend(function(e, xhr, options) {
        xhr.setRequestHeader(_hc, _tc);
    });

Spring Security의 CSRF Token을 다음과 같은 자바스크립트 변수로 설정할 수 있습니다.MyApp.csrfToken.

문서가 준비되면 JSP에서 진행 중인 스크립트를 추가하여 init 함수를 호출합니다.

<script type="text/javascript">
    document.onreadystatechange = function () {
       var state = document.readyState;
       if (state == 'complete') {
         fnInit("${_csrf.parameterName}", "${_csrf.token}"); 
       }
    }​;
</script>

JS 파일에서 다음을 정의합니다.fnInit기능.

var MyApp = MyApp || {};
function fnInit(csrfParam, csrfToken) {
  MyApp.csrfToken = {
      param : csrfParam,
      value : csrfToken
  }
}

이제 토큰을 어떤 아약스 통화에서도 사용할 있습니다.

...
...
xhttp.open("POST", "http://localhost:8080/bids?q="+selected + "&"+ MyApp.csrfToken.param+"="+ MyApp.csrfToken.value,  true);
xhttp.send();

추신: jQuery는 필요 없고, 순수한 자바스크립트입니다.

언급URL : https://stackoverflow.com/questions/37383730/how-to-add-csrf-token-to-ajax-request