2016-09-01 14 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> 

やミドルウェアからのinit:

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

答えて

0

私は知りません明示的ですが、通常はCSRFトークンがクッキー内にあるので、これらの2つの機能が必要になります:

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 
    } 
}); 

それともあなたはAJAXリクエストを作るためにはXMLHttpRequestを使用することができ、jQueryのを使用しない場合:

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

唯一の理由このメソッドは、あなたのajaxリクエストでCookieを渡していないということでは機能しません。私はコードを調べるときに私がそれを理解するときに苦労していた。

Csurfは、クッキー(_csrf)に保存されている秘密鍵を渡す必要があります。クッキーは、私の場合には(CORSを許可するサーバーを除く)ドメインに基づく許可による制限

を持って、私は、同じドメインの要求にクッキーを渡すへfetchを使用します(私は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

関連する問題