2014-06-13 6 views
8

Ich benutze eine Third-Party-Bibliothek, die eine rohe XMLHttpRequest mit new XMLHttpRequest hervorbringt.X-CSRF-Token-Header global zu allen Instanzen von XMLHttpRequest() hinzufügen;

Dies umgeht meinen CSRF-Schutz und wird von meinem Rails-Server abgeschossen.

Gibt es eine Möglichkeit zum globalen Hinzufügen eines vordefinierten CSRF-Tokens ($('meta[name=csrf-token]').attr('content')) zu allen Instanzen von XMLHttpRequest zur Instanziierungszeit?

+0

haben Sie versucht, [ '$ .ajaxPrefilter'] (http://api.jquery.com/jQuery.ajaxPrefilter/)? Und hier ist ein Beispiel: [Hinzufügen von CSRF-Token zu jQuery AJAX-Anfragen] (http://avinmathew.com/adding-csrf-token-to-jquery-ajax-requests/) – shawnzhu

+1

Warum wollen * Sie * drittens reparieren Bibliotheken, die nicht wissen, wie Sie Ihre API richtig kontaktieren können? – Bergi

+0

@shawnzhu: Nein, OP sagt, es ist eine * rohe * 'XMLHttpRequest'! – Bergi

Antwort

22

ich intercept calls zum send Methode empfehlen würde:

(function() { 
    var send = XMLHttpRequest.prototype.send, 
     token = $('meta[name=csrf-token]').attr('content'); 
    XMLHttpRequest.prototype.send = function(data) { 
     this.setRequestHeader('X-CSRF-Token', token); 
     return send.apply(this, arguments); 
    }; 
}()); 

Dieses gewonnen Fügen Sie die Kopfzeile nicht zur Instanziierungszeit hinzu, sondern direkt bevor die Anfrage gesendet wird. Sie kann abfangen Anrufe zu new XMLHttpRequest() als auch, aber das wird nicht hilfreich sein, wie Sie mit dem Hinzufügen der Kopfzeile warten müssen, bis open aufgerufen wurde.

Sie möchten vielleicht auch einen Test für die Ziel-URL der Anfrage einfügen, so dass Sie nur die Kopfzeile hinzufügen, wenn Ihre eigene API aufgerufen wird. Anderenfalls könnte das Token an anderer Stelle verloren gehen oder sogar domänenübergreifende CORS-Aufrufe, die diesen Header nicht zulassen, unterbrochen werden.

+0

Ich ging mit tun es nach dem Öffnen, so dass es angeklatschten werden kann, aber 6 von einem, ein halbes Dutzend der anderen nehme ich an ... – dandavis

+0

@dandavis: zunächst dachte ich, abfangen "offen" auch, aber ich didn ' Ich möchte nur den Code aus Ihrer Antwort wiederholen. Du hast +1 bekommen, gerade als ich deinen Beitrag gesehen habe :) – Bergi

+0

tolle Köpfe denken gleich. Kann ich fragen, ob du mit dieser Art von Mod 100% ig bist? es fühlt sich ein wenig riskant/schmutzig für mich an, obwohl ich den Schaden nicht sehen kann. – dandavis

4

Sie die Ajax-Methode open() wickeln kann zu öffnen und dann sofort den Header gesetzt:

(function() { 
    var op = XMLHttpRequest.prototype.open; 
    XMLHttpRequest.prototype.open = function() { 
     var resp = op.apply(this, arguments); 
     this.setRequestHeader('X-CSRF-Token', $('meta[name=csrf-token]').attr('content')); 
     return resp; 
    }; 
}()); 
1

Wenn Sie eine JQuery unabhängige Lösung benötigen könnten Sie verwenden:

(function() { 
     var send = XMLHttpRequest.prototype.send, 
      token = document.getElementsByTagName('meta')['csrf-token'].content; 
     XMLHttpRequest.prototype.send = function(data) { 
      this.setRequestHeader('X-CSRF-Token', token); 
      return send.apply(this, arguments); 
     }; 
    }());