Код: Выделить всё
@Component
@RequiredArgsConstructor
public class JWTAuthenticationFilterForWS implements ChannelInterceptor {
private final JwtUtility jwtUtil; // your existing JWT utility
private final UsersRepository usersRepository;
@Override
public Message preSend(Message message, MessageChannel channel) {
StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
if (StompCommand.CONNECT.equals(accessor.getCommand())) {
String token = accessor.getFirstNativeHeader("Authorization");
if (token != null && token.startsWith("Bearer ")) {
token = token.substring(7);
String username = jwtUtil.getUsernameFromToken(token);
// check user exists
usersRepository.findByUsername(username)
.orElseThrow(() -> new RuntimeException("Invalid JWT"));
// set user for STOMP session
accessor.setUser(new StompPrincipal(username));
} else {
throw new RuntimeException("No JWT token provided");
}
}else {
// For other STOMP commands like SEND, SUBSCRIBE, retrieve user safely
StompHeaderAccessor otherAccessor =
MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
if (otherAccessor != null) {
Principal user = otherAccessor.getUser();
System.out.println("Handling STOMP command " + accessor.getCommand() + " from user: " + user);
// Add any authorization logic for SEND, SUBSCRIBE here if needed
}
}
System.out.println("WebSocket connection established with user: " + accessor.getUser());
return message;
}
}
< /code>
Всякий раз, когда Stomp вызывает этот фильтр для отправки или подписки, он переходит к Block и печати «Команда Rading Stomp Send Send Null». Это означает, что если я обрабатываю метод отображения сообщений в контроллере, я не могу получить принципал-это NULL.
My Web Socket Config: < /p>
@Configuration
@EnableWebSocketMessageBroker
@RequiredArgsConstructor
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
private final JWTAuthenticationFilterForWS JWTAuthenticationFilterForWS;
@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
registration.interceptors(JWTAuthenticationFilterForWS);
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/chat").setAllowedOriginPatterns("*").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/topic");
registry.setApplicationDestinationPrefixes("/app");
}
}
< /code>
My JS Websocket Code выглядит следующим образом: < /p>
WebSocket Chat Tester
WebSocket Chat
JWT Token:
Connect
Disconnect
Send
[list][/list]
let stompClient = null;
function connect() {
const token = document.getElementById("jwtToken").value.trim();
if (!token) {
alert("Please enter JWT token");
return;
}
const socket = new SockJS('http://localhost:8080/chat'); // your endpoint
stompClient = Stomp.over(socket);
stompClient.connect(
{ Authorization: 'Bearer ' + token },
function(frame) {
console.log('Connected: ' + frame);
alert("Connected!");
// Subscribe to your chat topic (replace '1' with chatId)
stompClient.subscribe('/topic/chat', function(messageOutput) {
const msg = JSON.parse(messageOutput.body);
const li = document.createElement("li");
li.innerText = `[${msg.timestamp}] ${msg.sender}: ${msg.content}`;
document.getElementById("messages").appendChild(li);
});
},
function(error) {
console.error('STOMP error: ' + error);
alert('Error connecting: ' + error);
}
);
}
function disconnect() {
if (stompClient !== null) {
stompClient.disconnect(function() {
console.log("Disconnected");
alert("Disconnected!");
});
}else {
alert("Not connected!");
}
}
function sendMessage() {
const msgInput = document.getElementById("chatMessage").value.trim();
if (!msgInput) return;
if (stompClient && stompClient.connected) {
stompClient.send(
'/app/message',
{},
JSON.stringify({ content: msgInput })
);
document.getElementById("chatMessage").value = '';
} else {
alert("Not connected!");
}
}
Подробнее здесь: https://stackoverflow.com/questions/797 ... l-for-stom