网站 平均加载时间,绍兴网站网站建设,wordpress图片远程,重庆专业网站推广费用最近在建设 websocket 长连接网关#xff0c;过程中遇到一件比较奇怪的事情#xff0c;做下简单的记录。需求十分的简单#xff0c;websocket 网关在做权限校验的时候期望复用现有登录逻辑的 jwt-token。如下图所示#xff0c;sso 与 websocket 网关属于不同的二级域名过程中遇到一件比较奇怪的事情做下简单的记录。需求十分的简单websocket 网关在做权限校验的时候期望复用现有登录逻辑的 jwt-token。如下图所示sso 与 websocket 网关属于不同的二级域名登录的 jwt-token cookie 的 domain 设置为 *.xx.com。所以我们的期望是浏览器与 websocket 网关进行 handshark 请求时可以带上 jwt-token cookie。结果自然是不行的服务端并没有收到来自 *.xx.com 的 cookie。于是开始考虑可能和跨域行为有关系。CORSCORS 是一种用于解决跨域的 w3c 标准全称为 跨域资源共享(Cross-origin resource sharing)。它允许浏览器向跨源服务器发出 XMLHttpRequest 请求从而克服了 AJAX 只能同源使用的限制。CORS 基于 http 协议关于跨域方面的规定使用时客户端浏览器直接异步请求被调用端服务端在响应头增加响应的字段告诉浏览器后台允许跨域。概括的说CORS 就是服务端对跨域权限的控制由一组标准的 header 来控制客户端的跨域行为不同浏览器对于 CORS 的实现均有不同。常用的 CORS header 主要有Access-Control-Allow-Origin 指示请求的资源能共享给哪些域可以是具体的域名或者 * 表示所有域。Access-Control-Allow-Credentials 指示当请求的凭证标记为 true 时是否响应该请求。Access-Control-Allow-Headers 用在对预请求的响应中指示实际的请求中可以使用哪些 HTTP 头。Access-Control-Allow-Methods指定对预请求的响应中哪些 HTTP 方法允许访问请求的资源。CORS 处理请求的流程如下判断当前请求是否简单请求。如果不是简单请求则会使用 OPTIONS 方法先发起一个预检请求 (PreFlight)预检请求通过返回的 response 里设置了对应的 header 并匹配上了才会进行下一步具体的请求。预检请求后会发起实际请求但会根据返回的 response header 来决定请求行为例如根据服务端设置的 Access-Control-Allow-Credentials 值来决定请求是否携带当前域的 cookie。这里涉及到的简单请求和非简单请求的概念那么简单请求和非简单请求有什么区别呢若请求满足所有下述条件则该请求可视为简单请求使用了下列 HTTP 方法GET、HEAD、POST。只用了以下 headerAccept、Accept-Language、Content-Language、Content-Type(有额外限制)、DPR、Downlink、Save-Data、Viewport-Width、Width。请求中的任意 XMLHttpRequestUpload 对象均没有注册任何事件监听器XMLHttpRequestUpload 对象可以使用 XMLHttpRequest.upload 属性访问。请求中没有使用 ReadableStream 对象。经过一番简单的科普回到我们的问题上来。浏览器对 websocket 的 handshark 请求会不会应用同源策略呢。我们先不回答先来看看如果 CORS 应用在 websocket 上会是什么样的。首先一个 websocket 的握手连接报文大概如下GET / HTTP/1.1Upgrade: websocketConnection: UpgradeHost: ws.xx.comOrigin: http://www.xx.comSec-WebSocket-Key: sB9cRrP/a9NdMgdcy2VJFXSec-WebSocket-Version: 11它和普通 HTTP 请求的区别是多了两行 headerUpgrade: websocketConnection: Upgrade显然它们不属于 CORS 安全的 header 集合自然浏览器会认为这不是一个 简单请求。那么它会按照发起 预检请求随后根据返回的 response header 来判断下一步行为。此处我们希望能带上当前域的 cookie那么按照 CORS 标准我们需要在服务端做一些配置让其支持 CORS 并带上 Access-Control-Allow-Credentials 为 true 的 response header。我们使用的是 Netty 来构建 websocket 网关Netty 支持 CORS 很简单CorsConfig corsConfig CorsConfigBuilder.forAnyOrigin().allowNullOrigin().allowCredentials().build();pipeline.addLast(new CorsHandler(corsConfig));结果是什么呢我们的 websocket 服务端正确拿到了 *.xx.com 的 cookie并完成了后续鉴权工作。websocket 需要 CORS 么所以真相是什么呢websocket 也需要 CORS 支持来避免跨域问题么google 任何 websocket 与跨域相关的问题都会告诉你websocket 本身就是支持跨域的websocket 本身没有同源策略也就是说在第一幅图中我们应该不作任何事就可以把 xx.com 的 cookie 带到 ws.xx.com 的 websocket 网关上去这似乎和我们实际情况不符。我们使用的是 chrome后来突发奇想试了下 firefox 与 safari结论是这两者不用配置任何 CORS 相关属性就可以把 cookie 带上。难道这是 chrome 的一个 bug? 翻了翻网络找到了一个似乎可以应征的 bug report: Cookies not sent in Websocket handshake with cookies blocked and domain whitelisted (https://bugs.chromium.org/p/chromium/issues/detail?id947413)作者fredalxin来源链接https://fredal.xin/websocket-cors-problem