任务描述
我为我的角度应用程序实施了 CRSF 保护。服务器检查 crsf 令牌是否放置在请求的标头"X-CSRF-TOKEN"中。如果不是,则发送http响应403。
在我的客户端中,我拦截所有请求并检查是否返回 http 响应 403。在这种情况下,我发送一个HEAD请求,以便从服务器获取crsf令牌,该令牌在响应的标头"X-CSRF-TOKEN"中返回。
从服务器获取令牌后,我在标头"X-CSRF-TOKEN"中使用给定的 crsf 令牌重新发送原始请求。
问题描述
这适用于所有浏览器,除了Internet Explorer(尝试IE 9和10)。在本地(没有代理和防火墙),它也可以与Internet Explorer一起使用。但是在我们的生产环境中,head 请求在 360 秒内处于挂起状态,但随后返回预期的响应。
我不确定发生了什么。为什么它在本地主机上工作,但在生产环境中不起作用?可能是代理的问题吗?但是为什么它适用于所有其他浏览器(chrome,火狐等)?即使在 6 分钟后,IE 也会得到正确答案并按预期进行。对我来说,这看起来不像是代理问题。那么,这是IE的问题吗?但是为什么它在本地主机上工作?
IE和其他浏览器的请求的唯一区别是标头中的引用器: - 在IE中,引用看起来像 http://url/context-root/#/login - 在其他浏览器中,引用看起来像 http://url/context-root/
本地环境和生产环境之间的区别在于,代理拦截请求并进行一些上下文重写并打开 https 隧道。服务器实际上使用 http,然后代理通过隧道传输请求。
有谁知道问题可能是什么?
这是我的角度模块,它注册了http拦截器:
'use strict';
(function () {
angular.module('csrf-token-interceptor', [])
.config(function ($httpProvider) {
var csrfToken = { headerName: 'X-CSRF-TOKEN', token: null };
var getCsrfToken = function () {
var xhr = new XMLHttpRequest();
xhr.open('head', '/context-root/index.html?id=' + new Date().toString(), false);
xhr.send();
return { headerName: 'X-CSRF-TOKEN', token: xhr.getResponseHeader('X-CSRF-TOKEN') };
};
var numRetries = 0;
var MAX_RETRIES = 1;
$httpProvider.interceptors.push(function ($q, $injector) {
return {
request: function (config) {
config.headers[csrfToken.headerName] = csrfToken.token;
return config || $q.when(config);
},
responseError: function (response) {
if (response.status === 403 && numRetries < MAX_RETRIES) {
csrfToken = getCsrfToken();
var $http = $injector.get('$http');
++numRetries;
return $http(response.config);
}
return $q.reject(response);
},
response: function(response) {
numRetries = 0;
var newToken = response.headers(csrfToken.headerName);
if (newToken !== null) {
csrfToken.token = newToken;
}
return response;
}
};
});
});
})();
这些请求如下所示:
- 开机自检 http://url/context-root/#/login,时间:53ms,状态:403
- 头 http://url/context-root/index.html?id=..., 时间: 360,2秒, 状态: 200
- 开机自检 http://url/context-root/#/login, 时间: 49ms, 状态: 200
这可能是 IE 中与您使用 HEAD
方法相关的错误;请参阅 https://connect.microsoft.com/IE/feedback/details/1023203/xhr-readystate-done-delay-on-head-request
您是否使用像 Fiddler 这样的代理观察过您的网络流量?如果是这样,您可以分享流量捕获吗?