当从Ember发布到后端时,CSRF不匹配

首先,我只想说我已经阅读了与此主题相关的所有其他主题,但没有任何运气。 以下是问题的细目:

目标

  • 当Ember应用程序启动时从Sails检索CSRF令牌
  • 将CSRF令牌注入从Ember应用程序启动的每个AJAX请求中
  • 为了满足目标1,我创建了一个Ember初始化程序,当应用程序首次启动时运行(如果有更好的地方,我完全接受建议)。 为了实现目标2,我从Sails中检索CSRF令牌,然后尝试使用Ember.$.ajaxSetup()以确保CSRF令牌作为头( X-CSRF-Token )或参数( _csrf_csrf 。 我也确保我使用withCredentials选项来确保cookie已设置。 代码如下:

    // initializers/csrf.js
    import Ember from 'ember';
    import config from '../config/environment';
    
    export function initialize() {
      Ember.$.get(config.APP.API_URL + '/csrfToken').then(function(result) {
        Ember.$.ajaxSetup({
          data: {
            '_csrf': result._csrf
          },
          xhrFields: { withCredentials: true }
        });
      }, function(error) {
        console.log(error);
      });
    }
    
    export default {
      name: 'csrf',
      initialize: initialize
    };
    

    所有这些似乎都能正常工作,正如我在Chrome开发工具中所看到的那样,CSRF令牌正在被检索,并且当我发出AJAX请求时,我会将数据附加到POST数据或添加为标题(尝试这两种选项)。 以下是我正在运行的代码以及所有关联的标题:

    Ember.$.post(config.APP.API_URL + '/auth/register', {
      'email': _this.get('email'),
      'password': _this.get('password')
    }).then(function(response) {
      console.log('It worked!');
    });
    

    请求标题

    POST /auth/register HTTP/1.1
    Host: localhost:1337
    Connection: keep-alive
    Content-Length: 82
    Accept: */*
    Origin: http://localhost:4200
    CSP: active
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36
    Content-Type: application/x-www-form-urlencoded; charset=UTF-8
    DNT: 1
    Referer: http://localhost:4200/signup
    Accept-Encoding: gzip, deflate
    Accept-Language: en-US,en;q=0.8
    Cookie: sails.sid=s%3AbrABhErTY3-ytTWOKFJ2KBj7DCAzaLDc.apD60Sd%2BW85GSbTfJ7E3B2PrUwnhOsW6GlNpZTu9jFg
    

    表格数据

    _csrf:yP7GDiU2-YGmLBfBvQtMPT3-hRpnfK0x-AfA
    email:test@test.com
    password:q1w2e3r4
    

    响应头

    HTTP/1.1 403 Forbidden
    Vary: X-HTTP-Method-Override
    Access-Control-Allow-Origin: http://localhost:4200
    Access-Control-Allow-Credentials: true
    Content-Type: text/html; charset=utf-8
    Content-Length: 13
    Date: Thu, 09 Jul 2015 08:11:34 GMT
    Connection: keep-alive
    

    正如你从Response头看到的,我最终收到了来自Sails的403 Forbidden - CSRF Mismatch 。 现在,这里有点奇怪:首先,我可以用Postman运行这个。 我检索一个令牌,然后将该令牌与数据一起发送到/auth/register url,并按预期工作。

    我也尝试删除初始化程序并运行以下代码:

    Ember.$.ajaxSetup({
      xhrFields: { withCredentials: true }
    });
    
    Ember.$.get(config.APP.API_URL + '/csrfToken').then(function(result) {
      Ember.$.post(config.APP.API_URL + '/auth/register', {
        'email': _this.get('email'),
        'password': _this.get('password'),
        '_csrf': result._csrf
      }).then(function(response) {
        console.log('It worked!');
      });
    });
    

    这工作。 然而,在这一点上,我对这个问题实际上有些不知所措。 感谢任何帮助,我可以得到。

    提前致谢! 詹姆士


    @ jdixon04,您可以在通过POST发送之前尝试使用URL编码CSRF令牌吗? 如果令牌从原始变更,则会发生令牌不匹配。

    我在Github发现了这个问题:https://github.com/balderdashy/sails/issues/2266。

    我希望这能解决你的问题。 请尝试一下,让我知道它是否有效。 谢谢。


    @ jdixon04,从我的github问题的帖子中获得了。 实际上,每次向服务器发出的请求都不会改变CSRF令牌吗? 然后,当前端负载无法应付此问题时,您可以修复该令牌,您可能必须在每个请求前获取令牌并使用ajaxPrefilter将其传递给请求。

    这实际上是与呃数据 - 帆? 在我看来,你在这里做纯粹的ajax! 如果你看看我的配置,你会意识到纯粹的ajax调用(用于身份验证)可以免除csrf,因为我无法按照我的意愿使其工作:。


    像这样添加x-csrf-token标头:

    Ember.$.ajaxSetup({
      headers: {
        'X-CSRF-TOKEN': result._csrf
      },
      xhrFields: { withCredentials: true }
    });
    
    链接地址: http://www.djcxy.com/p/86575.html

    上一篇: CSRF Mismatch When POSTing from Ember to Sails Backend

    下一篇: Double clicking on headers of NSOutlineView is triggering double