AngularJS没有发送-X_XSRF-TOKEN

 用户0h2eqqbg44 发布于 2022-12-29 17:03

我正在开发一个Ionic移动应用程序,Rails使用JSON API 与我的后端服务器通信.我已经读过,如果第一个请求返回一个名为的cookie ,AngularJS将通过X-XSRF-TOKENPOST请求上发送标头来自动处理XSRF保护GETXSRF-TOKEN

我更新了我的Rails application_controller.rb如下:

class ApplicationController < ActionController::Base
  protect_from_forgery
  after_filter :set_access_control_headers
  after_filter :set_csrf_cookie_for_ng

  def after_sign_in_path_for(resource)
    main_path
  end

  def after_sign_out_path_for(resource)
    login_path
  end

  ##
   # Sets headers to support AJAX Cross-Origin Resource Sharing.
   # This is only needed for testing within browser (i.e. mobile apps do not need it).
   ##
  def set_access_control_headers
    # hosts who can make AJAX requests
    headers['Access-Control-Allow-Origin'] = 'http://localhost:8100'
    headers['Access-Control-Request-Method'] = '*'
    headers['Access-Control-Allow-Headers'] = 'accept, content-type, x-xsrf-token'
    # allow clients to use cookies to track session state
    headers['Access-Control-Allow-Credentials'] = 'true'
  end

  ##
   # Sets a cookie containing an XSRF token. This should be returned by the
   # client as a header field named 'X-XSRF-TOKEN'
  def set_csrf_cookie_for_ng
    cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery?
  end

protected

  def verified_request?
    super || form_authenticity_token == request.headers['X-XSRF-TOKEN']
  end
end

AngularJS代码是:

$http({
  method: 'POST',
  url: $scope.getBackendUrl() + '/reports.json',
  params: params,
  withCredentials: true,
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  }
})

我已经进行了Wireshark转储,可以看到Rails服务器正在通过Cookie发送(我可以在AngularJS中读取它).但是,AngularJS没有将标头发X-XSRF-TOKEN送到我的后端Rails服务器,导致了WARNING: Can't verify CSRF token authenticity.

我读过一堆SO问题无济于事.例如, 未在AngularJS中设置XSRF标头

我添加了CORS头文件,以便我可以从Chrome测试.再次,我可以看到cookie来自服务器,但标题没有被发回.但是,cookie将在"Cookie"标题字段中发回.

任何人都可以看到我所缺少的东西,或者我可以尝试解决这个问题的事情吗?我目前正在解析Cookie请求中的头字段以提取令牌并检查真实性以在测试时解决问题.

def verified_request?
  # should just need to do the below, but for some reason AngularJS is not setting 'X-XSRF-TOKEN'
  #super || form_authenticity_token == request.headers['X-XSRF-TOKEN']
  if(super)
    true
  else
    cookie = request.headers['Cookie'] || ""
    value = cookie.nil? ? "" : CGI.unescape( cookie.gsub(/.*XSRF-TOKEN=(.+);.*/, '\1') )
    form_authenticity_token == value
  end
end

版本:

Rails 3.2.3

Ionic 1.1.6(在AngularJS中捆绑)

Jeremy Wilke.. 13

根据文件

$ http:不会为跨域请求设置标头.

如果必须使用CORS,您还需要进行跨域请求.仍然可以使用$ httpInterceptor自己完成.您首先读取cookie值,然后在触发请求之前将标头附加到配置.

function readCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1,c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
}
module.factory('XSRFInterceptor', function() {
    var XSRFInterceptor = {
        request: function(config) {
            var token = readCookie('XSRF-TOKEN');
            if (token) {
                config.headers['X-XSRF-TOKEN'] = token;
            }
            return config;
        }
    };
    return XSRFInterceptor;
}]);
module.config(['$httpProvider', function($httpProvider) {
    $httpProvider.interceptors.push('XSRFInterceptor');
}]);


Eugene.. 9

对于像我一样来到这里的人试图找出为什么Angular没有发送X-XSRF-TOKEN标头:

在我的情况下,我没有注意到我正在发送带有HttpOnly标志的XSRF-TOKEN cookie .

2 个回答
  • 根据文件

    $ http:不会为跨域请求设置标头.

    如果必须使用CORS,您还需要进行跨域请求.仍然可以使用$ httpInterceptor自己完成.您首先读取cookie值,然后在触发请求之前将标头附加到配置.

    function readCookie(name) {
        var nameEQ = name + "=";
        var ca = document.cookie.split(';');
        for(var i=0;i < ca.length;i++) {
            var c = ca[i];
            while (c.charAt(0)==' ') c = c.substring(1,c.length);
            if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
        }
        return null;
    }
    module.factory('XSRFInterceptor', function() {
        var XSRFInterceptor = {
            request: function(config) {
                var token = readCookie('XSRF-TOKEN');
                if (token) {
                    config.headers['X-XSRF-TOKEN'] = token;
                }
                return config;
            }
        };
        return XSRFInterceptor;
    }]);
    module.config(['$httpProvider', function($httpProvider) {
        $httpProvider.interceptors.push('XSRFInterceptor');
    }]);
    

    2022-12-29 17:05 回答
  • 对于像我一样来到这里的人试图找出为什么Angular没有发送X-XSRF-TOKEN标头:

    在我的情况下,我没有注意到我正在发送带有HttpOnly标志的XSRF-TOKEN cookie .

    2022-12-29 17:05 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有