WebSocket Stomp over SockJS - http自定义标头

时间:2014-08-25 13:22:13

标签: spring websocket stomp sockjs stompjs

我在我的javascript客户端中使用stomp.js而不是SockJS。 我使用

连接websocket
stompClient.connect({}, function (frame) {

stomp over sockJS连接有2个http请求:

  1. 请求/ info
  2. http升级请求
  3. 客户端发送所有cookie。我还想发送自定义标头(例如XSRF标头),但没有找到办法。将不胜感激任何帮助。

4 个答案:

答案 0 :(得分:7)

@Rohitdev 因此,基本上您无法使用stompClient发送任何 HTTP 标头,因为STOMP是基于websockets的层,只有当websockets握手发生时,我们才有可能发送自定义标头。 因此,只有SockJS可以发送此标题,但出于某些原因,请勿执行此操作:https://github.com/sockjs/sockjs-client/issues/196

答案 1 :(得分:5)

自定义标题:

stompClient.connect({token: "ABC123"}, function(frame) { ... code ...});

没有自定义标题:

stompClient.connect({}, function(frame) { ... code ...});

在Javascript中,您可以使用以下方法提取STOMP标头:

  username = frame.headers['user-name'];

在服务器端,如果您使用的是Spring Framework,则可以实现一个Interceptor来将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");


      ...
    }
}

对于没有STOMP参数的发送消息:

function sendMessage() {
     var from = document.getElementById('from').value;
     var text = document.getElementById('text').value;
            stompClient.send("/app/chatchannel", {},
               JSON.stringify({'from':from, 'text':text}));
}

在这里,您将参数传递给STOMP标题。

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}));
}

答案 2 :(得分:0)

如果您在服务器上使用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变量,并且必须为getterssetterscontructor

在前端使用Stomp

用法-

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

要增加安全性,请在Spring中使用CORS

答案 3 :(得分:-6)

来自 http://jmesnil.net/stomp-websocket/doc/

stompClient.connect(headers,connectCallback,errorCallback);

其中header是包含自定义HTTP标头的地图