WebSocket Stomp over SockJS - http custom headers
@RohitdevSo 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
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}));}
Use @Header(name = "token")
annotation inside the method if you are using Spring boot at the server.
Usage -
@Controllerpublic 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