WebSocket Stomp over SockJS - http custom headers

这一生的挚爱 提交于 2021-02-17 21:25:33

问题


I'm using stomp.js over SockJS in my javascript client. I'm connecting to websocket using

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

stomp over sockJS connection has 2 http requests:

  1. request to /info
  2. http upgrade request

the client sends all cookies. I would like to also send custom headers (e.g. XSRF header) but didn't find a way to do that. Will appreciate any help.


回答1:


@Rohitdev So basically you can't send any HTTP headers using stompClient, because STOMP is layer over websockets, and only when websockets handshake happen we have possibility to send custom headers. So only SockJS can send this headers, but for some reasons don't do this: https://github.com/sockjs/sockjs-client/issues/196




回答2:


Custom headers:

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

Without Custom headers:

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

In Javascript, you can extract an STOMP header using:

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

In the server side, if you are using Spring Framework you can implementa an Interceptor to copy the HTTP parmeters to WebSockets STOMP headers.

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


      ...
    }
}

And for send messages without STOMP parameters:

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

and here you are passing parameters into the STOMP headers.

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



回答3:


Use @Header(name = "token") annotation inside the method if you are using Spring boot at the server.

Usage -

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

You should have a MessageModel class with message variable and required getters, setters and contructor.

In frontend use Stomp

Usage -

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

To add more security you an use CORS in Spring



来源:https://stackoverflow.com/questions/25486889/websocket-stomp-over-sockjs-http-custom-headers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!