全局添加X-CSRF-Token标头到XMLHttpRequest()的所有实例;

时间:2014-06-13 00:48:13

标签: javascript ajax security xmlhttprequest csrf

我正在使用第三方库,它使用XMLHttpRequest生成原始new XMLHttpRequest

这绕过了我的CSRF保护并被我的rails服务器击落。

有没有办法在实例化时向$('meta[name=csrf-token]').attr('content')的所有实例全局添加预定义的CSRF令牌(XMLHttpRequest

3 个答案:

答案 0 :(得分:26)

我建议intercept calls使用send方法:

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

这不会在实例化时添加标头,而是在发送请求之前。您也可以拦截对new XMLHttpRequest()的来电,但这不会有用,因为您需要等待添加标头,直到调用open

您可能还希望包含对请求的目标URL的测试,以便您只在调用自己的api时添加标头。不这样做可能会将令牌泄露到其他位置,甚至可能会破坏不允许此标头的跨域CORS呼叫。

答案 1 :(得分:5)

你可以将ajax open()方法打开,然后立即设置标题:

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

答案 2 :(得分:3)

如果您需要Jquery独立解决方案,您可以使用:

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