2016-09-01 2 views
2

CSRF 보호를 위해 고속 미들웨어 csurf를 사용하고 있습니다. 양식과 함께 토큰을 숨겨진 필드에 넣으면 경로 뒤에있는 작업이 작동합니다. 이제는 간단한 AJAX 호출을 만들고 싶지만 csurf는 무효라고 말합니다.csurf AJAX 호출 - CSRF 토큰이 유효하지 않습니다.

AJAX 호출 :

$('.remove').on('click', function() { 
    var csrf = $(this).attr('data-csrf'); 
    $.ajax({ 
     type: 'DELETE', 
     url: '/user/' + $(this).attr('data-id'), 
     data: { 
      _csrf: csrf 
     }, 
     success: function (data) { 
      //..... 
     } 
    }); 
}); 

그리고 뷰의 부분 :

<td class="uk-table-middle"> 
    <button data-id="{{ _id }}" data-csrf="{{ csrfToken }}" class="uk-button-link uk-text-large remove"> 
     <i class="uk-icon-remove"></i> 
    </button> 
</td> 

그리고 미들웨어에서 초기화 :

import * as csurf from 'csurf'; 
// init bodyparse and and and... 
app.use(csurf()); 

답변

0

내가 알고하지 않습니다 표현하지만 보통 CSRF 토큰은 쿠키 안에 있으므로이 두 가지 기능이 필요합니다. : 다음

function getCookie(name) { 
    var cookieValue = null; 
    if (document.cookie && document.cookie != '') { 
     var cookies = document.cookie.split(';'); 
     for (var i = 0; i < cookies.length; i++) { 
      var cookie = jQuery.trim(cookies[i]); 
      // Does this cookie string begin with the name we want? 
      if (cookie.substring(0, name.length + 1) == (name + '=')) { 
       cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 
       break; 
      } 
     } 
    } 
    return cookieValue; 
} 

function csrfSafeMethod(method) { 
    // these HTTP methods do not require CSRF protection 
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 
} 

과 :

var csrftoken = getCookie('csrftoken'); 
$.ajax({ 
    url : formURL, 
    type: "POST", 
    data : postData, 
    beforeSend: function(xhr, settings){ 
     if (!csrfSafeMethod(settings.type)) xhr.setRequestHeader("X-CSRFToken", csrftoken); 
    }, 
    success:function(data, textStatus, jqXHR){ 

    }, 
    error: function(jqXHR, textStatus, errorThrown){ 
        //if fails 
    } 
}); 

아니면 jQuery를 사용하지 않으려면, 당신은 AJAX 요청하기 위해 XMLHttpRequest의를 사용할 수 있습니다

var csrftoken = getCookie('csrftoken'); 
var xhr = new XMLHttpRequest(); 

xhr.open('POST', url); 
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
xhr.setRequestHeader("X-CSRFToken", csrftoken); 
xhr.onload = function(){ 
    if(xhr.status === 200){ 
     var response = JSON.parse(xhr.responseText); 
     console.log(response) 
    } 
}; 
xhr.send(encodeURI('category=' + cat)); 
+0

이것은 도움이되지 않았습니다. 작동하지 않는 이유는 배열과 토큰을 템플릿에 보내는 것입니다. 그리고 템플릿에서 배열을 반복하고이 범위에서 토큰을 찾지 못했습니다 .... 그 사실을 알지 못했습니다. – R3Tech

0

유일한 이유 왜 이 방법은 작동하지 않습니다. 아약스 요청으로 쿠키를 전달하지 않는 것입니다. 코드를 조사 할 때 알아 내려고 고심하고있었습니다.

Csurf는 쿠키 (_csrf)에 저장된 비밀 키를 전달해야합니다. 쿠키

내 경우에

, 나는 같은 도메인 요청과 함께 쿠키를 전달하는 fetch을 사용 (CORS 수 있도록 서버 제외) 도메인을 기반으로 권한을 통해 제한이

(내가 CORS를 허용 할 필요가 없습니다)
const { _csrf, someData } = jsonData; // _csrf here you got from the form 
const response = await fetch("/api/some/endpoint", { 
    method: "POST", 
    credentials: "same-origin", // here is the option to include cookies on this request 
    headers: { 
    "x-csrf-token": _csrf, 
    "Content-Type": "application/json" 
    }, 
    body: JSON.stringify({ someData }) 
}); 

위의 코드를주의하십시오. 저는 es6 형식을 사용하고 있습니다. 라이브러리로 jQuery를 사용하는 경우 CORS see the doc here a.k.a 다른 도메인으로

를 요청하는 경우가 includesame-origin을 변경할 수 있습니다,이 코드는 당신에게 도움이 될 수 있습니다. 이 코드는 테스트되지 않았으므로 사용하는 라이브러리에 따라 직접 찾아야합니다.

$.ajax({ 
    url: 'http://your.domain.com/api/some/endpoint', 
    xhrFields: { withCredentials: true }, // this include cookies 
    headers: {'x-csrf-token': 'YourCSRFKey'} 
}) 

_csrf 값을 전달할 때를 쿼리 문자열 헤더, 후 데이터 또는 에 자신의 이름을 자유롭게 사용하시기 바랍니다. 위의 예에서 이름이 x-csrf-token 인 헤더를 사용하지만 아래 스크린 샷 코드를 기반으로 다른 방법을 사용할 수 있습니다.

Sample code from csurf when geting _csrf value

관련 문제