maa*_*nus 3 browser caching browser-cache http-headers
我遇到一个无辜的请求后,我的客户端被注销了.我控制了两端,经过大量的调试后,我发现发生了以下情况:
304 Not Modified没有任何Authorization标头.据我所知,浏览器不得缓存包含授权的任何请求.尽管如此,
chrome://view-http-cache/http://localhost:10080/api/SearchHost
Run Code Online (Sandbox Code Playgroud)
节目
HTTP/1.1 200 OK
Date: Thu, 23 Nov 2017 23:50:16 GMT
Vary: origin, accept-encoding, authorization, x-role
Cache-Control: must-revalidate
Server: 171123_073418-d8d7cb0 =
x-delay-seconds: 3
Authorization: Wl6pPirDLQqWqYv
Expires: Thu, 01 Jan 1970 00:00:00 GMT
ETag: "zUxy1pv3CQ3IYTFlBg3Z3vYovg3zSw2L"
Content-Encoding: gzip
Content-Type: application/json;charset=utf-8
Content-Length: 255
Run Code Online (Sandbox Code Playgroud)
有趣的服务器头由一些内部信息替换Jetty服务器头(出于安全原因不应该提供) - 忽略它.这就是curl所说的:
< HTTP/1.1 304 Not Modified
< Date: Thu, 23 Nov 2017 23:58:18 GMT
< Vary: origin, accept-encoding, authorization, x-role
< Cache-Control: must-revalidate
< Server: 171123_073418-d8d7cb0 =
< ETag: "zUxy1pv3CQ3IYTFlBg3Z3vYovg3zSw2L"
< x-delay-seconds: 3
< Content-Encoding: gzip
Run Code Online (Sandbox Code Playgroud)
这也发生在Firefox中,虽然我目前无法重现它. RFC继续,看起来上面链接的答案不准确:
除非响应中存在允许存储此类响应的缓存指令
看起来响应是可缓存的.没关系,我确实希望缓存内容,但我不希望从缓存中提供Authorization标头.这可能吗?
我的服务器用于Authorization仅在响应登录请求时发送标头.这曾经很好地工作,问题来自新的要求.
我们的网站允许用户任意长时间登录(我们没有敏感的业务).我们正在更改授权令牌的格式,因此我们不希望强制所有用户再次登录.因此,我让服务器在看到过时但有效的授权令牌时发送更新的授权令牌.所以现在任何响应都可能包含授权令牌,但大多数都没有.
将仍然有效的响应与过时的授权令牌相结合的浏览器缓存会受到阻碍.
作为一种解决方法,我在服务器发送etag授权令牌时发送no .它有效,但我更喜欢一些更清洁的解决方案.
链接答案中的引用具有误导性,因为它省略了一个重要部分:"如果缓存是共享的".这是正确的引用(RFC7234第3节):
高速缓存绝不能存储对任何请求的响应,除非:... 如果共享高速缓存,则授权头字段(参见[RFC7235]的第4.2节)不会出现在请求中,
RFC的那部分基本上是一个摘要.这是完全相同的规则(RFC7234第3.2节),它基本上是相同的:
甲共享高速缓存必须不使用与授权报头字段中的高速缓存的响应于请求(第4.2 [RFC7235]),以满足任何后续请求,除非高速缓存指令,允许存储这样的响应的存在的响应.
浏览器是否缓存共享缓存?RFC的简介部分对此进行了解释:
相反,私有缓存专用于单个用户; 通常,它们被部署为用户代理的组件.
这意味着浏览器缓存是私有缓存.它不是共享缓存,因此上述规则不适用,这意味着Chrome和Firefox都能正确执行其工作.
现在的解决方案.
该规范建议在没有Authorization标头的情况下重用包含Authorization的缓存响应的可能性.不幸的是,它还说该功能没有得到广泛实施.
因此,我能想到的最简单也是最具前瞻性的解决方案是确保包含授权令牌的任何响应都不会被缓存.例如,每当服务器看到过时但有效的授权令牌时,发送新的有效令牌Cache-Control: no-store以禁止缓存.
此外,您必须永远不要Cache-Control: must-revalidate使用Authorization标头发送,因为该must-revalidate指令实际上允许缓存响应,包括共享缓存,这可能会在将来导致更多问题.
...除非响应中存在允许存储此类响应的缓存指令.
在本规范中,以下Cache-Control响应指令(第5.2.2节)具有以下效果:must-revalidate,public和s-maxage.