websocket可以攜帶cookie嗎?為什麼?如果可以,怎樣做到呢?

王铁柱6發表於2024-12-07

WebSocket本身不能直接攜帶Cookie。Cookie是HTTP協議的一部分,而WebSocket是獨立於HTTP的協議,雖然它通常使用HTTP協議進行初始握手。

原因:

  • 不同的協議: Cookie的設計是與HTTP請求/響應週期緊密相關的。它透過HTTP頭部在客戶端和伺服器之間來回傳遞。WebSocket建立連線後,就脫離了HTTP協議,維持一個持久連線,不再有HTTP請求/響應的概念,因此也就沒有地方存放Cookie。
  • 不同的目的: Cookie主要用於維護HTTP會話狀態,例如使用者身份驗證、會話ID等。WebSocket連線本身就維護了一個持久連線,可以透過應用層協議自行管理狀態,不需要依賴Cookie。

如果需要在WebSocket連線中傳遞類似Cookie的資訊,可以採用以下方法:

  1. 在WebSocket連線URL中新增引數: 可以在WebSocket連線URL中新增查詢引數來傳遞資訊。例如:wss://example.com/socket?token=123456&user=abc。伺服器端可以解析URL中的引數獲取所需資訊。這種方式比較簡單,但引數會暴露在URL中,安全性較低。

  2. 在WebSocket握手階段的HTTP頭部中傳遞: 在WebSocket初始連線的HTTP握手請求中,可以自定義頭部來傳遞資訊。伺服器端可以在握手響應中也設定相應的頭部。這種方式相對安全一些,但需要客戶端和伺服器端都支援自定義頭部。

  3. 在WebSocket連線建立後,透過自定義訊息傳遞: 這是最常用的方法。在WebSocket連線建立後,客戶端可以傳送一條自定義訊息給伺服器,其中包含需要傳遞的資訊,例如使用者token、使用者資訊等。伺服器端收到訊息後,解析訊息內容即可。這種方式最為靈活,安全性也較高,可以根據需要傳遞任意資訊。

前端示例 (JavaScript):

// 方法一:在URL中新增引數
const socket = new WebSocket('wss://example.com/socket?token=' + userToken);

// 方法三:在連線建立後傳送自定義訊息
const socket = new WebSocket('wss://example.com/socket');

socket.onopen = () => {
  socket.send(JSON.stringify({ type: 'auth', token: userToken, user: userName }));
};

socket.onmessage = (event) => {
  const data = JSON.parse(event.data);
  // 處理伺服器返回的訊息
};

後端示例 (Python with websockets庫):

async def handler(websocket):
    # 方法一:從URL引數獲取資訊
    query_params = parse_qs(websocket.path_qs)
    token = query_params.get('token', [None])[0]

    # 方法三:從自定義訊息獲取資訊
    async for message in websocket:
        data = json.loads(message)
        if data.get('type') == 'auth':
            token = data.get('token')
            user = data.get('user')

        # ... 處理其他訊息 ...

選擇哪種方法取決於具體的需求和安全要求。通常情況下,推薦使用第三種方法,即在連線建立後透過自定義訊息傳遞資訊,這樣更加靈活和安全。

相關文章