Open wongakim-99 opened 1 month ago
WebSocketConfig 는 스프링이 웹소켓을 활성화하고 메시지 브로커를 설정하는 핵심 클래스이다. 이 클래스는 웹소켓을 통해 클라이언트와 서버가 양방향 통신을 할 수 있게 해준다.
Redis 는 pub/sub 메시징을 통해 여러 클라이언트가 같은 채팅방에서 실시간으로 메시지를 공유할 수 있게 해준다. RedisConfig는 외부 Redis 서버와의 연결을 설정하고, EmbeddedRedisConfig는 테스트 환경에서 사용할 수 있는 임베디드 Redis 설정을 제공할 수 있다.
ChatController는 클라이언트가 웹소켓을 통해 전송한 메시지를 받아서 처리하는 역할을 한다. 이 컨트롤러는 클라이언트와 서버 간 메시지 통신을 담당하며, 일반적으로 WebSocket으로부터 메시지를 수신하고 이를 브로커에게 전달한다.
ChatRoomController는 채팅방 생성, 입장, 나가기 등 채팅방과 관련된 HTTP 요청을 처리. 웹소켓 연결 전 단계에서 사용자가 어느 채팅방에 입장할지를 결정하는 중요한 역할을 한다.
RedisSubscriber는 Redis pub/sub 메시지를 구독하여 메시지를 실시간으로 수신하는 역할을 한다. 클라이언트가 채팅방에 메시지를 보내면, Redis가 이를 다른 구독자에게 전송한다.
이 클래스는 채팅방을 저장하고 관리하는 역할을 한다. 채팅방 정보를 메모리나 데이터베이스에서 관리하며, 채팅방 목록을 제공하거나 새로운 채팅방을 생성하는 역할을 한다.
이 클래스는 JWT(Json Web Token) 인증 및 토큰 생성을 담당. 채팅 기능에서 사용자의 인증 상태를 확인하거나, 웹소켓 연결 전에 사용자를 인증하는 데 사용될 수 있음.
ChatMessage는 실제로 클라이언트와 서버 간에 주고받는 메시지의 구조를 정의한 DTO이다. 채팅방에서 주고받는 메시지의 타입, 내용, 송신자 등의 정보가 포함된다.
ChatRoom은 각 채팅방의 정보를 저장하는 데이터 전송 객체이다. 채팅방의 ID, 이름 등을 저장하며, 채팅방 생성 시 사용된다.
※틀린부분 있으면 또 다시 수정할 예정
StompHandler는 WebSocket을 통해 들어오는 요청의 헤더에 담긴 JWT 토큰을 검증하는 역할을 하는 클래스. STOMP 프로토콜을 기반으로 동작하며, WebSocket 연결 및 메시지 전송 시에 보안 처리 역할을 담당.
StompHandler는 WebSocket 연결 시 JWT 토큰을 검증하여 인증된 사용자만 연결을 허용하는 보안 역할을 수행합니다. JwtTokenProvider와의 협업을 통해, 이 클래스는 WebSocket 통신의 중요한 인증 단계를 담당하고 있습니다.
EmbeddedRedisConfig 클래스는 로컬 환경에서 내장형 Redis 서버를 실행하고 종료하는 설정을 담당합니다. 이 코드를 통해 개발 환경에서 실제 Redis 서버 없이도 테스트할 수 있도록 임베디드 Redis 서버를 사용합니다.
RedisConfig 클래스는 Redis와의 연결 및 메시지 처리를 설정하는 매우 중요한 부분입니다. 이 코드는 Redis의 pub/sub 시스템을 설정하고, 메시지 처리, 리스너 등록, RedisTemplate 등을 정의합니다.
채널 설정: channelTopic() 메서드에서 "chatroom"이라는 Redis 채널을 생성합니다. 이는 클라이언트들이 메시지를 주고받는 특정 채널을 지정하는 역할을 합니다.
리스너 설정: redisMessageListener() 메서드는 Redis에서 발행된 메시지를 구독하기 위한 리스너를 설정합니다. 이 리스너는 "chatroom" 채널에 발행된 메시지를 구독하고, 해당 메시지를 RedisSubscriber 클래스의 sendMessage 메서드로 전달합니다.
메시지 처리: listenerAdapter() 메서드에서는 RedisSubscriber 클래스의 sendMessage 메서드를 리스너로 등록합니다. 즉, Redis에서 발행된 메시지가 들어오면 sendMessage 메서드를 통해 처리됩니다.
RedisTemplate 설정: Redis에 데이터를 저장하거나 가져올 때 사용하는 템플릿으로, 키와 값을 직렬화하는 방법을 설정합니다. 이 설정을 통해 Redis에 간단히 데이터를 저장하고 불러올 수 있습니다.
@Bean
public ChannelTopic channelTopic() {
return new ChannelTopic("chatroom");
}
@Bean
public RedisMessageListenerContainer redisMessageListener(RedisConnectionFactory connectionFactory,
MessageListenerAdapter listenerAdapter,
ChannelTopic channelTopic) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.addMessageListener(listenerAdapter, channelTopic);
return container;
}
@Bean
public MessageListenerAdapter listenerAdapter(RedisSubscriber subscriber) {
return new MessageListenerAdapter(subscriber, "sendMessage");
}
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(String.class));
return redisTemplate;
}
Spring Security를 사용하여 애플리케이션의 보안 설정을 정의하는 WebSecurityConfig 클래스입니다. 이 설정은 주로 WebSocket 채팅 애플리케이션에서 사용자 인증 및 권한을 처리하는 역할을 하며, 개발 및 테스트 환경에서는 In-Memory로 사용자 데이터를 저장해 간단히 인증을 구현하는 구조입니다.
이 코드는 WebSocket 기반 채팅 애플리케이션에서 간단한 보안 설정을 적용하며, 특히 In-Memory 사용자 관리와 Spring Security를 통해 기본적인 인증 및 권한 부여를 설정합니다. 개발 및 테스트 목적으로 설계된 코드이므로, 실제 운영 환경에서는 데이터베이스와 연동하여 사용자 정보를 관리하고, 적절한 비밀번호 인코더를 사용하는 것이 필수적입니다.
이 WebSockConfig 클래스는 WebSocket 메시지 브로커를 설정하는 역할을 합니다. 이 코드는 STOMP 프로토콜을 사용하여 WebSocket 연결을 관리하고, 메시지를 전송하는 경로를 정의하며, STOMP 핸들러를 통해 WebSocket 요청의 보안 및 기타 처리 작업을 관리합니다.
WebSocket을 통해 들어오는 채팅 메시지를 처리하고, 이를 Redis를 통해 다른 클라이언트에게 전달하는 역할을 합니다. 이 컨트롤러는 특히 WebSocket 통신과 Redis pub/sub 시스템을 사용하여 채팅 메시지를 실시간으로 관리합니다.
JwtTokenProvider jwtTokenProvider: JWT 토큰에서 사용자의 닉네임 또는 이름을 추출하는 역할을 합니다. 메시지 발신자를 인증된 사용자로 설정하기 위해 사용됩니다.
ChannelTopic channelTopic: Redis의 채널을 정의합니다. 채팅 메시지는 이 토픽을 통해 발행(publish)되어 여러 클라이언트에게 전파됩니다.
이 컨트롤러는 WebSocket을 통해 받은 채팅 메시지를 처리하고, 이를 Redis의 pub/sub 시스템을 통해 다른 클라이언트들에게 전파하는 역할을 합니다. JWT 토큰을 사용해 사용자 인증을 처리하고, 채팅방에 입장한 사용자를 알리는 기능도 포함되어 있습니다.
이 ChatRoomController 클래스는 채팅방 관리와 사용자 정보 조회를 처리하는 컨트롤러입니다. 주요 기능은 새로운 채팅방을 생성하거나, 채팅방 목록을 조회하고, 특정 채팅방에 대한 정보를 제공하는 역할을 합니다. 또한, JWT 토큰을 생성해 사용자 정보를 제공하는 기능도 포함되어 있습니다.
이 IndexController는 매우 간단한 컨트롤러로, 사용자가 애플리케이션의 루트 경로 (/ 또는 /index)로 접근할 때 채팅방 목록 페이지로 리다이렉트시키는 역할을 합니다. 이 컨트롤러는 애플리케이션의 기본 페이지를 설정하는 기능을 담당합니다.
dto(Data Transfer Object) 패키지에는 애플리케이션에서 사용되는 데이터를 클라이언트와 서버 간에 전송하기 위한 객체들이 정의되어 있습니다. 여기서는 채팅 메시지, 채팅방, 로그인 정보와 관련된 세 가지 DTO 클래스가 정의되어 있습니다.
채팅 메시지와 관련된 정보를 다루는 DTO로, 메시지 타입, 채팅방 ID, 발신자, 메시지 내용을 포함합니다.
채팅방 정보를 관리하는 DTO로, 채팅방 ID와 이름을 포함하며, 새 채팅방을 생성할 수 있습니다.
로그인된 사용자 이름과 해당 사용자의 JWT 토큰을 제공하는 DTO입니다.
이 DTO들은 서버와 클라이언트 간 데이터를 주고받는 데 중요한 역할을 하며, 각 클래스는 특정 기능에 맞춰 데이터를 관리합니다.
RedisSubscriber 클래스는 Redis pub/sub 시스템을 활용하여 Redis에서 발행된 메시지를 구독하고 처리하는 역할을 담당합니다. Redis에서 발행된 메시지를 받아서 이를 WebSocket을 통해 채팅방에 구독한 클라이언트들에게 전달하는 기능을 합니다.
SimpMessageSendingOperations: Spring의 메시지 전송 템플릿으로, STOMP(WebSocket의 서브 프로토콜)를 사용해 WebSocket 연결을 통해 클라이언트들에게 메시지를 전송할 수 있게 합니다.
이 템플릿은 특정 경로로 메시지를 발송하는 데 사용됩니다. 구독한 경로로 메시지를 전송하여 해당 경로를 구독한 클라이언트들이 실시간으로 메시지를 받을 수 있게 합니다.
ChatMessage chatMessage = objectMapper.readValue(publishMessage, ChatMessage.class);
messagingTemplate.convertAndSend("/sub/chat/room/" + chatMessage.getRoomId(), chatMessage);
ChatRoomRepository 클래스는 Redis를 이용하여 채팅방을 저장하고 관리하는 역할을 수행합니다. 이 클래스는 Redis의 Hash 자료구조를 사용해 채팅방 정보를 저장하며, 채팅방 목록을 조회하거나 새로운 채팅방을 생성하는 기능을 제공합니다.
JwtTokenProvider 클래스는 JWT(Json Web Token)를 생성하고, 검증하며, 복호화하여 사용자 정보를 얻는 역할을 합니다. JWT는 주로 사용자 인증과 세션 관리를 위해 사용되며, 이 클래스는 사용자의 이름을 포함한 토큰을 생성하고, 이를 검증하는 기능을 제공합니다.
WebSocket을 이용한 실시간 채팅 기능을 구현하기 위한 다양한 구성 요소들이 어떻게 유기적으로 상호작용하는지 보여줌. 각 클래스는 서로 역할을 나누어 특정 기능을 담당하고 있으며, 이를 통해 JWT 기반 사용자 인증, Redis를 통한 실시간 메시지 처리, 그리거 WebSocket 통신이 가능
흐름 :
흐름:
흐름:
이번 이슈에서 SpringSecurity와 JWT를 이용하여 Web 및 Websocket의 보안을 좀 더 강화하고, 이전 이슈에서의 복잡한 로직을 최소한 간소화 예정