2012-05-23 4 views
5

나는 csrf 토큰을 사용하여 내 웹 응용 프로그램을 보호하고 싶습니다. 내 질문은 어떻게 그 토큰을 다시 서버에 보내야합니까 : 쿼리 매개 변수 또는 http 헤더 x-csrf-token을 사용하고 있습니까? https://github.com/senchalabs/connect/blob/master/lib/middleware/csrf.jscsrf 토큰 사용

모든 : http://www.senchalabs.org/connect/csrf.html

당신이있어 주석 소스를 체크 아웃 할 수 있습니다

그리고 무엇을 당신이 Express를 사용하고 있기 때문에

답변

9

, 당신은 (연결로)의 CSRF 미들웨어를 사용할 수의 차이입니다 그 미들웨어를 포함시킨 다음 POST 양식 (또는 상태를 변경시키는 요청이 무엇이든 PUT 등)에 _csrf 변수의 값을 req.session._csrf으로 설정하십시오. 여기

확인 예 : https://github.com/senchalabs/connect/blob/master/examples/csrf.js

UPDATE

연결이 대신 req.session._csrf

전체 예제의 req.csrfToken()를 사용해야합니다 2.9.0 버젼 : 커밋 https://github.com/senchalabs/connect/blob/master/examples/csrf.js

: https://github.com/senchalabs/connect/commit/70973b24eb1abe13b2da4f45c1edbb78c611d250

을3210

UPDATE2

커넥트 미들웨어는 다른 모듈 (및 관련 REPOS)로 분할되었으며, 여기합니다 (CSRF 포함) 그들 모두를 찾을 수 있습니다 내 관점에서 https://github.com/senchalabs/connect#middleware

+0

네,이 알고 있지만 내가 사용하는 것이 좋습니다 알고 싶어 : 헤더 X-CSRF 토큰 또는 숨겨진 필드를? – Erik

+0

여기에서 볼 수있는 것처럼 https://github.com/senchalabs/connect/blob/master/lib/middleware/csrf.js # L69 Express는 먼저 POST 값을 확인한 다음 쿼리 문자열 값과 x-csrf-token 헤더를 확인하므로 값이있는 숨겨진 _csrf 필드를 전달하는 것이 가장 좋습니다. – alessioalex

+0

내가 사용해야하는 접근 방식은 무엇인가 아약스 요청에 csrf-token을 사용하고 싶습니까? – Erik

3

를 사용한다 양식을 제출할 때 숨겨진 필드에 csrf POST 매개 변수 이것이 유일한 방법입니다.

그러나 AJAX 요청의 경우 X-CSRF-Token 헤더를 대신 사용하시기 바랍니다. 주로, 제대로 완료되면 각 POST 요청에 토큰을 추가하는 번거 로움을 덜어주기 때문입니다. 또는 jQuery Form과 같은 라이브러리를 사용할 때, 제출시 추가 POST 매개 변수를 추가하는 것은 해킹이 될 수 있습니다.

예를 들어 AJAX 요청에 jQuery를 사용하면 a hook이 제공되므로 요청하기 전에 X-CSRF-Token을 자동으로 투명하게 설정할 수 있습니다. 따라서 클라이언트 측 코드 수정이 거의 필요하지 않습니다. 그리고 코드의 awesomeness 폭등.

-

장고의 하나를 기반으로 내가 거의 성공적으로 내 모든 프로젝트를 사용 예제 구현은, 다음과 같습니다 서버 측에

jQuery(document).ajaxSend(function(event, xhr, settings) { 

    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 sameOrigin(url) { 
    // url could be relative or scheme relative or absolute 
    var host = document.location.host; // host + port 
    var protocol = document.location.protocol; 
    var sr_origin = '//' + host; 
    var origin = protocol + sr_origin; 
    // Allow absolute or scheme relative URLs to same origin 
    return (url == origin || url.slice(0, origin.length + 1) == origin + '/') || 
      (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') || 
      // or any other URL that isn't scheme relative or absolute i.e relative. 
      !(/^(\/\/|http:|https:).*/.test(url)); 
    } 

    function safeMethod(method) { 
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 
    } 

    if (!safeMethod(settings.type) && sameOrigin(settings.url)) { 
    xhr.setRequestHeader("X-CSRFToken", getCookie('csrf.token')); 
    } 
}); 

, 당신은 단지 좋겠 클라이언트가 토큰을 쉽게 얻을 수 있도록 CSRF 토큰을 포함하는 쿠키를 설정해야합니다. 내가 가진 app.use(express.csrf()) 대체 :

app.use((function(options) { 

    var csrf = express.csrf(options); 

    return function(req, res, next) { 

    function onCsrfCalled() { 
     var token = req.session._csrf; 
     var cookie = req.cookies['csrf.token']; 

     // Define a cookie if not present 
     if(token && cookie !== token) { 
     res.cookie('csrf.token', token); 
     } 

     // Define vary header 
     res.header('Vary', 'Cookie'); 

     next(); 
    } 

    csrf(req, res, onCsrfCalled); 
    } 
})());