Implementing WebSocket Authentication
1. Understanding WebSocket Auth Challenges
| Challenge | Detail |
| No custom headers | Browser cannot set headers on WS handshake (only cookies/sub-protocols/query) |
| Long-lived | Token may expire mid-connection |
| CSWSH | Cross-Site WebSocket Hijacking — must check Origin |
2. Implementing Handshake Authentication
Example: Verify in upgrade
wss.on("connection", async (ws, req) => {
const origin = req.headers.origin;
if (!ALLOWED.has(origin)) return ws.close(1008);
const cookies = parse(req.headers.cookie || "");
const user = await verifySession(cookies.sid);
if (!user) return ws.close(1008);
ws.user = user;
});
3. Using Query Parameters for Tokens
Warning: Tokens in URL leak to logs, browser history, referrer. Use only short-lived single-use tickets.
4. Implementing Cookie-Based Authentication
| Aspect | Detail |
| Cookie sent | Browser includes session cookie automatically |
| Cross-origin | Use SameSite=None; Secure if cross-site |
| CSWSH protection | Validate Origin header strictly |
Native WS clients (Node, mobile) can set Authorization: Bearer ... on the HTTP upgrade. Not possible from browsers.
6. Implementing Token Refresh over WebSocket
| Strategy | Detail |
| Auth message | Client sends {type:"auth", token} over WS |
| Re-handshake | Close + reconnect with new token |
| Grace | Allow current operations to complete |
7. Handling Connection Authentication Failures
| Close Code | Meaning |
| 1008 | Policy violation (auth failed) |
| 4001-4999 | App-defined (custom auth errors) |
| Client | Don't auto-reconnect on 4xxx without UX prompt |
8. Implementing Heartbeat for Session Validation
Example: Ping with token check
setInterval(() => {
if (Date.now() > ws.user.exp * 1000) return ws.close(4001, "token_expired");
ws.ping();
}, 30_000);
9. Using Sub-Protocols for Auth
Example: Token via sub-protocol
// Browser
new WebSocket("wss://api.example/socket", ["bearer.token." + encodeURIComponent(jwt)]);
// Server reads Sec-WebSocket-Protocol header
10. Implementing Message-Level Authorization
| Pattern | Detail |
| Per-message check | Verify permission for each action |
| Subscription auth | Verify on subscribe (channel access) |
| Rate limit | Per-connection message throttle |