メインコンテンツにスキップ

Cookie の処理方法

cookie オプションを使用する場合、サーバーはハンドシェイク (セッションの最初の HTTP リクエスト) 時に Engine.IO セッション ID の値を含む Cookie を送信します。

const io = new Server(httpServer, {
cookie: true
});

// is similar to

const io = new Server(httpServer, {
cookie: {
name: "io",
path: "/",
httpOnly: true,
sameSite: "lax"
}
});

curl でテストできます。

$ curl "https://mydomain.com/socket.io/?EIO=4&transport=polling" -v
< HTTP/1.1 200 OK
< Content-Type: text/plain; charset=UTF-8
< Content-Length: 97
< Set-Cookie: io=G4J3Ci0cNDWd_Fz-AAAC; Path=/; HttpOnly; SameSite=Lax
<
0{"sid":"G4J3Ci0cNDWd_Fz-AAAC","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":20000}

使用可能なオプション (cookie パッケージより)

  • domain
  • encode
  • expires
  • httpOnly
  • maxAge
  • path
  • sameSite
  • secure

この Cookie は、複数ノードにスケーリングする場合に Cookie ベースのスティッキーセッションに使用できます (HAProxy の例はこちらにあります)。

アプリケーション Cookie

サーバーから送信されるヘッダーをカスタマイズすることもできます。

import { serialize, parse } from "cookie";

// called during the handshake
io.engine.on("initial_headers", (headers, request) => {
headers["set-cookie"] = serialize("uid", "1234", { sameSite: "strict" });
});

// called for each HTTP request (including the WebSocket upgrade)
io.engine.on("headers", (headers, request) => {
if (!request.headers.cookie) return;
const cookies = parse(request.headers.cookie);
if (!cookies.randomId) {
headers["set-cookie"] = serialize("randomId", "abc", { maxAge: 86400 });
}
});
注意

イベントエミッターは同期であることに注意してください。

io.engine.on("initial_headers", async (headers, request) => {
// WARNING! this won't work
const session = await fetchSession(request);
headers["set-cookie"] = serialize("sid", session.id, { sameSite: "strict" });
});

非同期操作を実行する必要がある場合は、allowRequest オプションを使用する必要があります。

参照用に、express-session を使用したこの例を確認してください。

Node.js クライアントと Cookie

バージョン 4.7.0 以降、withCredentials オプションを true に設定すると、Node.js クライアントは Cookie を HTTP リクエストに含むようになるため、Cookie ベースのスティッキーセッションで簡単に使用できるようになりました。