json - IE11 不设置 x-cfrtoken HTTP 标头,除非使用 InPrivate 窗口,这会导致服务器响应 HTTP 403 Access Denied
问题描述
我已经被这两天迷惑了。情况:
- 简单的网站,在 Websharper 中运行,登录屏幕,单一视图,通过带有应用程序/json 响应的 XHR
- 该站点在
iframe
具有不同域的内部运行(我无法更改,但我可以访问这两个站点)。没有 iframe 就没有问题。 - 您应该会看到登录错误的错误,但这在 Windows 7 上的 IE11 中不起作用。它在 InPrivate 模式下的相同 IE11 和 Windows 10 上的任何 IE11 中都有效。这不是缓存问题。
- 该站点设置了 cookie,但如果无法设置 cookie(即 iPhone),则该站点不使用 cookie
似乎在 InPrivate 模式下,x-csfrtoken
在请求标头中设置了 ,在 InPrivate 模式之外,此标头未设置。然后服务器返回 HTTP 403 错误,这似乎是问题的根源。
我不知道如何指示服务器 (IIS) 忽略此令牌。
要查看此行为的实际效果,请访问该站点并输入任何内容,然后单击“Inloggen”。您应该会看到登录错误(荷兰语),但在 Windows 7 上的 IE11 中,不会出现此错误。
我尝试了 Microsoft 的此解决方案LocalLow
,但它没有解决问题,而且似乎不相关。
解决方案
显然这是 Windows 7 和 Windows 8 / 8.1 上的 IE11 中的一个错误。我发现浏览器确实发送了csrftoken
cookie,但忘记了所需的x-csrftoken
HTTP Header 参数,所有其他浏览器,包括 Windows 10 上的旧版和新版 IE 和 IE11 都正确发送了该参数。
如果您的工具链通过验证x-csrftoken
(任何框架都推荐)来保护自己,那么 IE11 会失败。这里讨论了 WebSharper ,但还没有完整的解决方案。
我发现可以正常工作的解决方法如下。这很 hacky,它会在到达时更改 HTTP 标头,但其他工具也可以这样做(想想代理服务器)。如果您使用的是 WebSharper ,这里是放置在global.asax.fs
F# 中的代码(有点乱,但我会将清理工作留给读者作为练习;))。
member __.Application_BeginRequest(sender: obj, args: System.EventArgs) =
HttpContext.Current
|> function
| null -> ()
| ctx ->
match ctx.Request with
| null -> ()
| req ->
match req.Cookies.Item "csrftoken", req.Headers.Item "x-csrftoken" with
| null, null -> ()
| cookie, null ->
// fix for IE11, which does not always set the HTTP Header "x-csrftoken"
try req.Headers.Item "x-csrftoken" <- cookie.Value
with _ -> () // ignore possible errors
| null, _ ->
// if header is set but cookie is not, there's nothing we can do (cookie collection is read-only)
()
| cookie, csrfHeader when cookie.Value <> csrfHeader ->
try req.Headers.Item "x-csrftoken" <- cookie.Value
with _ -> () // ignore possible errors
| _ ->
() // all is fine, the default: cookie "csfrtoken" and header "x-csfrtoken" are equal
推荐阅读
- java - JMH - 为什么 JIT 不能消除我的死代码
- ios - 来自 webViewKit 按钮的用户权限单击
- android - 如何在 node.js 中使用套接字,以便使用 html 文件显式地分别响应客户端和管理员?
- package - 无法安装 twilio.AspNet mvc 包
- delphi - 任务栏上的图标不会移动到第二台显示器
- c# - 使用 pfx 文件加载证书
- json - 我如何将我的课程编码为 json 以将 http put 发送到 firebase
- r - 用于 mutate 的矢量化线性插值函数
- html - 向 VueDraggable (sortable.js) 添加拖出功能
- sql-server - SQL Server - 将每天的记录转换为日期范围(有间隙)