IE11 不会设置 x-cfrtoken HTTP header,除非使用 InPrivate window,这会导致服务器响应 HTTP 403 Access Denied
IE11 does not set x-cfrtoken HTTP header, unless with an InPrivate window, this causes server to respond with HTTP 403 Access Denied
这两天我都被这个搞糊涂了。情况:
- 简单的网站,运行在 Websharper 中,登录屏幕,单一视图,通过 XHR 和 application/json 响应
- 该站点 运行 来自具有不同域的
iframe
(我无法更改它,但我可以访问这两个站点)。没有 iframe 就没有问题。
- 您应该会看到错误登录错误,但这在 Windows 7 上的 IE11 中不起作用。它在 InPrivate 模式下的相同 IE11 和 [= 上的任何 IE11 中工作45=]10。这不是缓存问题。
- 该站点设置了 cookie,但如果无法设置 cookie(即 iPhone),则以无 cookie 的方式运行
看来在InPrivate模式下,请求header中设置了x-csfrtoken
,在InPrivate模式外这个header没有设置.然后服务器 returns 一个 HTTP 403 错误,这似乎是问题的根源。
我不知道如何指示服务器 (IIS) 忽略此标记。
要查看此行为的实际效果,请访问该站点并输入任何内容,然后单击 "Inloggen"。你应该看到 login-error(荷兰语),但在 Windows 7 上的 IE11 中,不会出现此错误。
I tried this solution by Microsoft, on improper rights on LocalLow
,但它没有解决问题,而且似乎与其他问题无关。
显然这是 Windows 7 和 Windows 8 / 8.1 上的 IE11 中的错误。我发现浏览器 确实 发送了 csrftoken
cookie,但是 忘记了 所需的 x-csrftoken
HTTP Header 参数,所有其他浏览器,包括旧版和新版 IE 和 Windows 10 上的 IE11 正确发送。
如果您的工具链通过验证 x-csrftoken
(任何框架都推荐)来保护自己,那么这将在 IE11 中失败。它was discussed here for WebSharper,但还没有一个完整的解决方案。
我发现可以正常工作的解决方法如下。它很老套,它会在到达时更改 HTTP headers,但其他工具也会这样做(想想代理服务器就是其中之一)。如果您使用的是 WebSharper,这里是放置在 F# 中的 global.asax.fs
中的代码(有点乱,但我将清理作为 reader ;) 的练习)。
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
这两天我都被这个搞糊涂了。情况:
- 简单的网站,运行在 Websharper 中,登录屏幕,单一视图,通过 XHR 和 application/json 响应
- 该站点 运行 来自具有不同域的
iframe
(我无法更改它,但我可以访问这两个站点)。没有 iframe 就没有问题。 - 您应该会看到错误登录错误,但这在 Windows 7 上的 IE11 中不起作用。它在 InPrivate 模式下的相同 IE11 和 [= 上的任何 IE11 中工作45=]10。这不是缓存问题。
- 该站点设置了 cookie,但如果无法设置 cookie(即 iPhone),则以无 cookie 的方式运行
看来在InPrivate模式下,请求header中设置了x-csfrtoken
,在InPrivate模式外这个header没有设置.然后服务器 returns 一个 HTTP 403 错误,这似乎是问题的根源。
我不知道如何指示服务器 (IIS) 忽略此标记。
要查看此行为的实际效果,请访问该站点并输入任何内容,然后单击 "Inloggen"。你应该看到 login-error(荷兰语),但在 Windows 7 上的 IE11 中,不会出现此错误。
I tried this solution by Microsoft, on improper rights on LocalLow
,但它没有解决问题,而且似乎与其他问题无关。
显然这是 Windows 7 和 Windows 8 / 8.1 上的 IE11 中的错误。我发现浏览器 确实 发送了 csrftoken
cookie,但是 忘记了 所需的 x-csrftoken
HTTP Header 参数,所有其他浏览器,包括旧版和新版 IE 和 Windows 10 上的 IE11 正确发送。
如果您的工具链通过验证 x-csrftoken
(任何框架都推荐)来保护自己,那么这将在 IE11 中失败。它was discussed here for WebSharper,但还没有一个完整的解决方案。
我发现可以正常工作的解决方法如下。它很老套,它会在到达时更改 HTTP headers,但其他工具也会这样做(想想代理服务器就是其中之一)。如果您使用的是 WebSharper,这里是放置在 F# 中的 global.asax.fs
中的代码(有点乱,但我将清理作为 reader ;) 的练习)。
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