日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

websocket 带头部信息请求 header_关于websocket跨域的一个奇怪问题

發布時間:2024/7/5 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 websocket 带头部信息请求 header_关于websocket跨域的一个奇怪问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近在建設 websocket 長連接網關,過程中遇到一件比較奇怪的事情,做下簡單的記錄。

需求十分的簡單,websocket 網關在做權限校驗的時候期望復用現有登錄邏輯的 jwt-token。如下圖所示,sso 與 websocket 網關屬于不同的二級域名,登錄的 jwt-token cookie 的 domain 設置為 *.xx.com。所以我們的期望是瀏覽器與 websocket 網關進行 handshark 請求時可以帶上 jwt-token cookie。

結果自然是不行的,服務端并沒有收到來自 *.xx.com 的 cookie。于是開始考慮可能和跨域行為有關系。

CORS

CORS 是一種用于解決跨域的 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。

  • 只用了以下 header:Accept、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.1

    Upgrade:?websocket

    Connection:?Upgrade

    Host:?ws.xx.com

    Origin:?http://www.xx.com

    Sec-WebSocket-Key:?sB9cRrP/a9NdMgdcy2VJFX==

    Sec-WebSocket-Version:?11

    它和普通 HTTP 請求的區別是多了兩行 header


    Upgrade:?websocket

    Connection:?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?id=947413)


    作者:fredalxin

    來源鏈接:

    https://fredal.xin/websocket-cors-problem

    總結

    以上是生活随笔為你收集整理的websocket 带头部信息请求 header_关于websocket跨域的一个奇怪问题的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。