websocket 鉴权必须在握手阶段完成,推荐通过 url 参数传递短期 jwt token 并由服务端校验签名、时效性及吊销状态;禁用连接后鉴权,避免未授权连接被滥用。

WebSocket 连接本身不携带 Cookie 或 HTTP 头(握手后即升级为二进制帧协议),因此无法像普通 HTTP 请求那样依赖服务端 Session 或中间件自动鉴权。在 HTML5 中,最常用且安全的做法是在 WebSocket 握手阶段通过 URL 参数或请求头传递 Token,并由服务端在 onUpgrade 或连接建立前完成校验。
Token 应放在 WebSocket 握手请求中,而非连接后发送
很多开发者误以为可以先建立连接,再发登录消息、等待服务端返回“鉴权成功”,这种做法存在明显风险:未鉴权的连接已打开,可能被滥用(如广播攻击、资源占用)。正确方式是把 Token 作为握手的一部分,在 TCP 连接升级为 WebSocket 前就拒绝非法请求。
-
推荐方式:URL 参数传 Token(简单兼容性好)
前端:new WebSocket("wss://api.example.com/ws?token=eyJhbGciOi...");
后端(如 Node.js + ws):从request.url解析查询参数,验证 JWT 签名、过期时间、白名单等,校验失败直接res.end()并返回 401。 -
进阶方式:自定义请求头(需服务端支持 + 浏览器允许)
普通WebSocket构造函数不支持设置 header,但可通过fetch+Response.upgrade()或代理层(如 Nginx)注入。更现实的是用反向代理统一添加Authorization头,后端从 upgrade request 中读取。
Token 必须具备时效性与可撤销能力
WebSocket 连接生命周期长(可能数小时),若 Token 永不过期,一旦泄露将长期有效。因此 Token 不应是长期凭证,而应是短期会话凭据(如 15–30 分钟),并配合服务端黑名单或 Redis 记录在线状态。
- 生成 Token 时设
exp字段,服务端校验必须检查是否过期; - 用户登出或敏感操作后,主动使当前 Token 失效(如存入 Redis,key 为 token hash,value 设为过期时间);
- 服务端握手时除 JWT 校验外,额外查一次缓存,确认该 Token 未被显式吊销。
避免在前端明文存储 Token(尤其是 localStorage)
WebSocket Token 和登录态 Token 应一致,若已用 HttpOnly Cookie 管理登录态,可考虑服务端生成一次性 WebSocket Token(one-time use),通过安全接口(HTTPS + CSRF 保护)获取,再用于 WS 连接。这样即使页面 XSS,也无法直接窃取长期凭证。
- 不直接把登录用的 JWT 放进 WS URL;
- 优先调用
/api/v1/ws-token获取短期专用 Token,响应头设Cache-Control: no-store; - 该接口本身需校验 Cookie 或 Authorization,确保只有合法用户能获取。
连接建立后仍需二次上下文绑定(可选但推荐)
握手鉴权只保证“连接发起者身份合法”,不代表后续每条消息都来自同一用户(如共享连接对象、多标签页复用)。可在首次消息中要求客户端上报用户 ID 或设备指纹,并和服务端 Session 关联。
- 服务端收到第一条文本消息时,解析
{"type":"identify","uid":"123"}; - 比对该 UID 是否与握手 Token 中声明的一致,不一致则关闭连接;
- 将该 WebSocket 实例绑定到用户 ID,后续广播/私信逻辑基于此 ID 而非 socket 对象本身。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











