Spring WebSocket在SockJS上跺脚-http自定义头

Spring WebSocket在SockJS上跺脚-http自定义头,spring,websocket,stomp,sockjs,stompjs,Spring,Websocket,Stomp,Sockjs,Stompjs,我在javascript客户端中使用stomp.js而不是SockJS。 我正在使用连接到websocket stompClient.connect({}, function (frame) { stomp over sockJS连接有2个http请求: 请求发送至/发送信息 http升级请求 客户端发送所有cookie。我也想发送自定义头(例如XSRF头),但没有找到方法。非常感谢您的帮助。@Rohitdev 所以基本上,您不能使用stompClient发送任何HTTP头,因为STOMP是W

我在javascript客户端中使用stomp.js而不是SockJS。 我正在使用连接到websocket

stompClient.connect({}, function (frame) {
stomp over sockJS连接有2个http请求:

  • 请求发送至/发送信息
  • http升级请求
  • 客户端发送所有cookie。我也想发送自定义头(例如XSRF头),但没有找到方法。非常感谢您的帮助。

    @Rohitdev 所以基本上,您不能使用stompClient发送任何HTTP头,因为STOMP是WebSocket之上的层,只有当WebSocket握手时,我们才有可能发送自定义头。 因此,只有SockJS可以发送此标头,但出于某些原因,请不要这样做:

    自定义标头:

    stompClient.connect({token: "ABC123"}, function(frame) { ... code ...});
    
    stompClient.connect({}, function(frame) { ... code ...});
    
    没有自定义标题:

    stompClient.connect({token: "ABC123"}, function(frame) { ... code ...});
    
    stompClient.connect({}, function(frame) { ... code ...});
    
    在Javascript中,您可以使用以下命令提取STOMP头:

      username = frame.headers['user-name'];
    
    在服务器端,如果您使用的是Spring框架,那么您可以实现一个拦截器来将HTTP参数复制到WebSockets STOMP头

    public class HttpSessionHandshakeInterceptor_personalised implements HandshakeInterceptor {
    
        @Override
        public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
                WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
    
    
            // Set ip attribute to WebSocket session
            attributes.put("ip", request.getRemoteAddress());
    
            // ============================================= CODIGO PERSONAL
            ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
            HttpServletRequest httpServletRequest = servletRequest.getServletRequest();
    //        httpServletRequest.getCookies();
    //        httpServletRequest.getParameter("inquiryId");
    //        httpServletRequest.getRemoteUser();
    
             String token = httpServletRequest.getParameter("token");
    
    
          ...
        }
    }
    
    function sendMessage() {
         var from = document.getElementById('from').value;
         var text = document.getElementById('text').value;
                stompClient.send("/app/chatchannel", {'token':'AA123'},
                   JSON.stringify({'from':from, 'text':text}));
    }
    
    在这里,您将参数传递到STOMP头中

    public class HttpSessionHandshakeInterceptor_personalised implements HandshakeInterceptor {
    
        @Override
        public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
                WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
    
    
            // Set ip attribute to WebSocket session
            attributes.put("ip", request.getRemoteAddress());
    
            // ============================================= CODIGO PERSONAL
            ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
            HttpServletRequest httpServletRequest = servletRequest.getServletRequest();
    //        httpServletRequest.getCookies();
    //        httpServletRequest.getParameter("inquiryId");
    //        httpServletRequest.getRemoteUser();
    
             String token = httpServletRequest.getParameter("token");
    
    
          ...
        }
    }
    
    function sendMessage() {
         var from = document.getElementById('from').value;
         var text = document.getElementById('text').value;
                stompClient.send("/app/chatchannel", {'token':'AA123'},
                   JSON.stringify({'from':from, 'text':text}));
    }
    
    如果在服务器上使用Spring boot,请在方法中使用
    @Header(name=“token”)
    注释

    用法-

    @Controller
    public class SocketController {
    
        static final String token = "1234";
    
        @MessageMapping("/send")
        @SendTo("/receive/changes")
        public Object notify(MessageModel message, @Header(name = "token") String header)throws Exception {
            if(!header.equals(token)) {
                // return when headers do not match
                return("Unauthorized");
            }
            // return the model object with associated sent message
            return new MessageModel(message.getMessage());
        } 
    }
    
    您应该有一个
    MessageModel
    类,该类包含
    message
    变量和必需的
    getter
    setters
    constructor

    在前端使用跺脚

    用法-

    function sendMessage() {
         var text = document.getElementById('text').value;
                stompClient.send("/send/message", {'token':'1234'},
                   JSON.stringify({'message':text}));
    }
    

    为了增加安全性,您在Spring中使用CORS看起来不可能将自定义HTTP头传递到WebSocket握手请求。这是可能的,但我不知道如何使用stomp客户端。您的问题解决了吗?我遇到了类似的问题,如果您有解决方案,我希望听听您的解决方案。在这种情况下,使用Cookie进行授权将允许您从任何网站完全访问SockJS与您的网站的通信。这是典型的CSRF攻击。(c) 首先,它在弹簧部分不起作用。第二:查看@IRus-answer了解为什么我可以用SockJs发送参数,我的实现正在工作。我没有看到头,无论我铸造了多少次ServerHttpRequestI确认,spring部分不工作,没有可用的“令牌”参数