我在我的 javascript 客户端中使用 stomp.js 而不是 SockJS。我正在使用连接到 websocket
stompClient.connect({}, function (frame) {
stomp over sockJS 连接有 2 个 http 请求:
- 请求/信息
- http升级请求
客户端发送所有 cookie。我还想发送自定义标头(例如 XSRF 标头),但没有找到方法。将不胜感激任何帮助。
@Rohitdev所以基本上你不能使用stompClient发送任何HTTP头,因为STOMP是websockets的层,只有当websockets握手发生时,我们才有可能发送自定义头。所以只有 SockJS 可以发送此标头,但由于某些原因不要这样做:https ://github.com/sockjs/sockjs-client/issues/196
自定义标题:
stompClient.connect({token: "ABC123"}, function(frame) { ... code ...});
没有自定义标题:
stompClient.connect({}, function(frame) { ... code ...});
在 Javascript 中,您可以使用以下方法提取 STOMP 标头:
username = frame.headers['user-name'];
在服务器端,如果您使用 Spring Framework,您可以实现一个拦截器来将 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}));
}
您必须使用查询作为参数而不是在标题中使用授权。(?query=token_2222) 示例:var socket = new SockJS('/ws?query=token_2222'); 然后像 Sergio 写的那样在 HandshakeInterceptor 中阅读它
@Header(name = "token")
如果您在服务器上使用 Spring Boot,请在方法内使用注释。
用法 -
@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
变量和 required的类getters
,setters
并且contructor
.
在前端使用 Stomp
用法 -
function sendMessage() {
var text = document.getElementById('text').value;
stompClient.send("/send/message", {'token':'1234'},
JSON.stringify({'message':text}));
}
为了增加安全性,您可以在 Spring 中使用 CORS