websocket需显式传递token或session id完成认证,服务端在握手阶段校验并绑定用户上下文,连接期间复用该身份做权限控制,同时需启用wss、ip/useragent校验及心跳签名等安全措施。

WebSocket本身不自动携带Cookie或Session信息,所以不能直接复用HTTP的Session机制做身份认证。必须在连接建立初期显式传递凭证,并在服务端完成校验,才能安全地将WebSocket连接与用户Session关联起来。
连接时传递Session ID或Token
客户端在发起WebSocket连接前,先从当前页面的Cookie或内存中获取有效凭证(如JSESSIONID、PHPSESSID,或更推荐的JWT Token),然后通过URL参数或自定义HTTP头(需服务端支持)传给服务端。
- 推荐方式:将Token拼在WebSocket URL里,例如
ws://example.com/ws?token=abc123;服务端解析后验证签名和有效期 - 不推荐依赖Cookie自动携带:浏览器虽会发送Cookie,但跨域场景下受限,且部分WebSocket库不保证携带完整请求头
- 避免明文传用户名密码:敏感信息绝不走URL参数,Token应有短时效+签名+绑定IP/UserAgent等防护
服务端校验并绑定用户上下文
WebSocket握手是HTTP请求,服务端可在upgrade前拦截,解析凭证,校验通过后再允许升级连接,并把用户身份信息(如user_id、role)挂载到WebSocket会话对象上。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- Node.js(ws库)示例:在
verifyClient钩子中读取req.url或req.headers.cookie,查Redis或数据库确认Session有效 - Java(Spring WebSocket)示例:实现
HandshakeInterceptor,从参数或Header取Token,调用AuthService验证,再将Principal存入attributes - 校验失败立即拒绝连接(返回401),不创建WebSocket会话,防止未授权长连接占用资源
连接生命周期内复用Session状态
一旦认证成功,服务端可将用户标识缓存在内存或Redis中,后续所有该连接的消息收发都基于此标识做权限控制,无需重复鉴权。
- 为每个WebSocket连接分配唯一sessionKey(如
ws_${userId}_${timestamp}),存入Redis并设置过期时间(略长于Session TTL) - 消息处理时,通过socket对象反查绑定的用户ID,再查角色/权限配置,决定是否允许执行某操作
- 用户登出或Session失效时,主动关闭对应WebSocket连接,并清理缓存中的会话映射
补充安全与容错措施
仅靠一次握手认证不够,还需应对重放、劫持、异常断连等场景。
- 启用wss(WebSocket over TLS),防止Token被中间人截获
- 服务端记录每个连接的首次IP和User-Agent,后续消息中可做轻量比对,发现异常触发二次验证
- 心跳包(ping/pong)中嵌入时间戳签名,防止连接被长期劫持复用
- 前端监听
onclose事件,在断连后自动清空本地Token缓存,避免下次连接误用过期凭证
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










