⚙ Web Socket 실시간 채팅 구현과 보안

김지윤·2024년 6월 21일
0

컴퓨터 네트워크

목록 보기
19/19

⭕ 사용 목적

<용감한 원정대> Project는 도움이 필요한 사람이 게시글을 올리면, 가까운 이웃이 채팅을 신청해 함께 문제를 해결하는 서비스이다.

사용 주체는 원정대와 의뢰인이고, 두 사람의 거래를 위해 채팅 기능을 구현하기로 했다.


⭕ 개발 과정

✔ 기술 선택

우리 Project의 Client는 React Framework로 개발 되었고, Server는 Springboot Framework로 개발 되었다. 그래서 Client와 Server가 통신할 때, 주로 Rest API를 사용하여 HTTP 통신을 한다.

HTTP 통신은 Client에서 먼저 요청을 보내면, Server가 그에 맞는 응답을 해주는 방식으로 Client → Server로 단 방향 통신이다.

하지만 우리 Project에서 구현 목표였던 채팅 기능은 Client가 요청하지 않아도 Server에서 메시지를 보내줘야 하기 때문에 단 방향 통신이 아닌, 양 방향 통신을 지원하는 기술이 필요했다.

양 방향 통신 기술을 지원하는 서비스를 찾아보았을 때, Web Socket 기술을 찾을 수 있었고, 우리는 여기서 조금 더 발전된 STOMP 기술을 사용하기로 했다.

STOMP를 사용한 이유는 메시지를 발신, 수신하는 과정이 신문 구독과 같은 구독 방법을 사용하기 때문에 구조화 되어 보였고, 우리 Project의 코드 구조 관리에 더 수월할 것 같다는 판단이 들었다.

그리고 Client에게 보내주는 메시지도 다음과 같이 형식이 구조화 되어있어, 메시지 형식을 따로 규격화 하지 않아도 된다는 장점이 있었다.

그래서 우리는 Web Socket, STOMP를 사용하여 Front-End와 다음과 같이 협업 하였다.



📌 채팅 Logic 설계

채팅 방 입장 시

Client에서 Web Socket 연결을 위해 handshake 과정을 수행하고, 통신하고자 하는 채팅 방을 구독한다.

✔ 메시지 발신 시

웹 소켓 연결을 완료한 사용자가 메시지를 발신 하면, Server는 해당 채팅 방을 구독하고 있는 모든 사용자에게 메시지를 전송해준다. (이 과정이 양방향 통신이다)


📌 JWT Token 검증

<용감한 원정대> Project에서는 사용자 인증 절차로 Spring Security의 JWT Token 인증 기술을 도입했다. 모든 API 통신은 이 검증 로직을 거치고, Server에 접속하게 된다.

하지만, Web Socket은 HTTP 통신을 위한 Token 검증 로직을 지나가지 않는다.

따라서 Web Socket 전용 Token 검증 로직을 따로 작성해 주어야 한다.

Interceptor 구현

STOMP의 Message Type에는 여러가지가 있는데 그 중 원하는 곳을 선택하여 Token 검증 로직을 넣을 수 있다.

우리는 Client에서 맨 처음 Web Socket 연결을 시도하는 Handshake 과정인 CONNECT 메시지에서 Token 검증을 하기로 했다.

내가 작성한 Token 검증 로직은 다음과 같다.

Interceptor를 이용하여 Web Socket 통신 이전에 다음의 과정을 거치게 한다.

Client에서 전송되어 온 Message 안에서 Token을 꺼내고 그 Token의 유효성을 검증 한다.

만약 Token 기한이 만료되었다면 JwtExpiredError 메시지를 Client에 전송 시키고, 올바른 Token이 아니라면 NotCorrectJwt 메시지를 Client에 전송 시킨다.


⭕ 개발 완료

위 과정을 통해 다음과 같은 채팅 기능을 구현해냈다.



✍ 회고

이번 Project를 개발하면서 양 방향 통신 기술을 처음 사용해보았고, 그 과정에서 통신 방향성에 대한 개념이 생겼다. 통신의 방향에는 Client → Server, Server → Client 단 방향 기술, Client ↔ Server 양 방향 기술들이 있고, 목적에 따라 필요한 기술들을 선택해서 사용하면 된다.

그리고 이 공부를 통해 우리 Project의 다른 기술을 도입할 때에 기여를 할 수 있었다. Project의 다른 기능에는 실시간으로 메시지 알림을 띄워주는 기능이 계획에 있었는데, 기술 선택 과정에서 어려움을 겪고 있었다.

하지만 통신 방향성을 공부하고 나니, Server → Client로 전송해주는 기술을 사용하면 된다는 것을 알게 되었고, 그에 맞는 기술인 SSE (Server Sent Event)를 도입해 알림 기능도 성공적으로 구현할 수 있었다.

목적에 맞는 기술들을 직접 선택하고, 개발까지 성공하면서 내가 좀 더 주체적인 개발자가 되고 있다는 것을 느꼈고, 앞으로 더 배움으로서 또 어떤 성장을 할 수 있을지 기대가 되었다.

profile
꾸준하게 공부하고 기록하는 개발자

0개의 댓글