2016-09-01 3 views
2

Ich verwende die Express-Middleware CSURF für CSRF-Schutz. Wenn ich es mit Formularen verwende, wo ich den Token in ein verstecktes Feld setze, funktioniert die Aktion hinter den Routen. Jetzt möchte ich einen einfachen AJAX-Anruf machen, aber dort sagt csurf seinen ungültigen.csurf AJAX-Aufruf - ungültiges CSRF-Token

AJAX-Aufruf:

$('.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) { 
      //..... 
     } 
    }); 
}); 

Und der Teil in der Ansicht:

<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> 

Und die init von der Middleware:

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

Antwort

0

Ich weiß nicht, in Express, aber normalerweise ist das CSRF-Token in einem Cookie, so dass Sie diese beiden Funktionen benötigen :

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

Und dann:

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

Oder wenn Sie jQuery nicht verwenden möchten, können Sie XMLHttpRequest verwenden, um die AJAX-Request zu machen:

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

das hat mir nicht geholfen. Der Grund, warum es nicht funktionierte, war, dass ich ein Array und das Token an die Vorlage sendete. Und in der Vorlage ich Iterate durch das Array und in diesem Bereich das Token nicht gefunden .... wusste nicht, dass ._. – R3Tech

0

Der einzige Grund, warum Diese Methode funktioniert nicht, wenn Sie keine Cookies mit Ihrer Ajax-Anfrage übergeben. Ich habe mich angestrengt, als ich es herausgefunden habe, als ich in den Code geschaut habe.

Csurf müssen Sie den geheimen Schlüssel übergeben, der auf Cookies gespeichert ist (_csrf). Cookies haben eine Begrenzung durch die Berechtigung für die Domäne Basis (mit Ausnahme des Servers ermöglicht CORS)

Auf meinem Fall verwende ich fetch die Cookies mit derselben Domain Anfrage vorbei (ich muss CORS nicht zulassen)

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

Bitte beachten Sie den obigen Code Ich benutze es6 Format. Sie können same-origin mit include ändern, wenn Sie auf andere Domäne a.k.a CORS anfordernden see the doc here

Wenn Sie jQuery als Bibliothek verwendet wird, könnte dieser Code für Sie nützlich sein. Dieser Code wurde nicht getestet und Sie sollten selbst herausfinden, welche Bibliothek Sie verwenden.

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

Bitte frei, Ihre eigenen Namen auf den Header verwenden, Post-Daten oder Abfragezeichen wenn die _csrf Wert übergeben. In meinem obigen Beispiel benutze ich den Header mit dem Namen x-csrf-token, aber Sie können eine andere Methode verwenden, die auf dem folgenden Screenshot-Code basiert.

Sample code from csurf when geting _csrf value

Verwandte Themen