扣子事件触发器安全加固手册:防止恶意payload注入、重放攻击与越权触发(含OWASP合规检查清单)
2026/8/6 7:55:06
上一篇讲了 WebSocket 的基础,这篇实现一个完整的聊天室——在线用户管理、群聊、私聊。
@ComponentpublicclassUserSessionManager{privatefinalMap<Long,String>onlineUsers=newConcurrentHashMap<>();privatefinalMap<String,Long>sessionUsers=newConcurrentHashMap<>();publicvoidonline(LonguserId,StringsessionId){onlineUsers.put(userId,sessionId);sessionUsers.put(sessionId,userId);}publicvoidoffline(StringsessionId){LonguserId=sessionUsers.remove(sessionId);if(userId!=null){onlineUsers.remove(userId);}}publicintonlineCount(){returnonlineUsers.size();}publicList<Long>allUserIds(){returnnewArrayList<>(onlineUsers.keySet());}publicbooleanisOnline(LonguserId){returnonlineUsers.containsKey(userId);}}@ComponentpublicclassChatWebSocketHandlerextendsTextWebSocketHandler{privatefinalUserSessionManagersessionManager;privatefinalSimpMessagingTemplatemessagingTemplate;@AutowiredpublicChatWebSocketHandler(UserSessionManagersm,SimpMessagingTemplatemt){this.sessionManager=sm;this.messagingTemplate=mt;}@OverridepublicvoidafterConnectionEstablished(WebSocketSessionsession){LonguserId=getUserIdFromSession(session);sessionManager.online(userId,session.getId());broadcast("系统",userId+" 上线了,当前在线 "+sessionManager.onlineCount()+" 人");}@OverrideprotectedvoidhandleTextMessage(WebSocketSessionsession,TextMessagemessage){LonguserId=getUserIdFromSession(session);Stringpayload=message.getPayload();ChatMessagemsg=JSON.parseObject(payload,ChatMessage.class);if(msg.getToUserId()==null){// 群聊:广播给所有在线用户messagingTemplate.convertAndSend("/topic/chat",Map.of("from",userId,"content",msg.getContent()));}else{// 私聊:只发给指定用户messagingTemplate.convertAndSendToUser(msg.getToUserId().toString(),"/queue/chat",Map.of("from",userId,"content",msg.getContent()));}}@OverridepublicvoidafterConnectionClosed(WebSocketSessionsession,CloseStatusstatus){LonguserId=getUserIdFromSession(session);sessionManager.offline(session.getId());broadcast("系统",userId+" 下线了");}}<script>// 连接varsocket=newWebSocket('ws://localhost:9090/chat');socket.onopen=function(){console.log('连接成功');};// 接收消息socket.onmessage=function(event){varmsg=JSON.parse(event.data);addMessage(msg);};// 发送群聊functionsendGroup(){socket.send(JSON.stringify({content:document.getElementById('input').value}));}// 发送私聊functionsendPrivate(toUserId){socket.send(JSON.stringify({toUserId:toUserId,content:document.getElementById('input').value}));}</script>@RestController@RequestMapping("/api/chat")publicclassChatController{@AutowiredprivateUserSessionManagersessionManager;@GetMapping("/online-count")publicResultVO<Integer>onlineCount(){returnResultVO.success(sessionManager.onlineCount());}}💡 觉得有用的话,点赞 + 关注【张老师技术栈】吧!每周更新 Java/Python/MySQL 实战干货,不让你白来。