개발자

Spring WebSocket 통신 중 HttpOnly 쿠키에 저장된 JWT 토큰 접근 문제

2024년 01월 23일조회 404

안녕하세요, Spring과 React를 활용하여 실시간 채팅 기능을 구현 중인 학생입니다. 현재 저희 시스템은 사용자가 로그인을 성공하면, JWT 토큰을 생성하여 이를 HttpOnly 쿠키에 저장하고 있습니다. 이후 해당 토큰을 이용해서 사용자의 인증 및 인가를 처리합니다. 그리고 웹소켓을 화룡해 채팅 기능을 구현하고 있는데, 사용자가 채팅 메시지를 웹소켓을 통해 서버로 전송할 때마다, 해당 사용자의 JWT 토큰을 검사하여 유효한 사용자인지 확인하려고 합니다. 그러나 현재 쿠키가 HttpOnly로 설정되어 있어서, React에서 쿠키에 접근할 수 없습니다. 따라서 웹소켓 메시지를 보낼 때마다 JWT 토큰을 메시지에 포함시키지 못하고 있습니다. 구글링해서 찾아보니 다른 개발자들의 경우 클라이언트에서 헤더에 토큰을 포함하여 서버로 전송하고, 서버에서는 StompHeaderAccessor의 getFirstNativeHeader 메서드를 사용하여 토큰을 받아 사용자 검증을 하는 방식을 주로 사용하는 것 같습니다. 그러나 저희 시스템에서는 이 방식을 사용할 수 없어, 다른 해결 방안을 찾고 있습니다. 현재 제가 생각한 방식은 웹소켓 연결 시 웹소켓 세션에 해당 사용자의 토큰값을 저장하여 채팅 메시지가 서버로 전송될 때마다, 웹소켓 세션에 저장된 토큰값을 검증하는 방식입니다. 만약, 이 방식을 사용한다면 사용자 토큰값의 유효 기간이 끝나면 리프래시 토큰을 사용한 사용자 토큰 재발급 방식은 사용자 웹 브라우저 쿠키에 접근하지 못하니 불가능한가요? HttpOnly 쿠키에 저장된 JWT 토큰을 웹소켓 통신에서 어떻게 활용할 수 있을지 조언해주시면 감사하겠습니다.

이 질문이 도움이 되었나요?
'추천해요' 버튼을 누르면 좋은 질문이 더 많은 사람에게 노출될 수 있어요. '보충이 필요해요' 버튼을 누르면 질문자에게 질문 내용 보충을 요청하는 알림이 가요.
profile picture
익명님의 질문

답변 1

백승훈님의 프로필 사진

HttpOnly의 값은 Javascript로 접근이 불가능하여 보안상 이점이 있습니다. 이건 역으로 말하자면 Javascript로는 접근이 안되야하고 가져올 수 없습니다. httpOnly 속성의 경우 서버에서 setCookie등을 통해 설정하면 이후 클라이언트의 추가 동작은 필요없습니다. 이후 통신 시 해당 Cookie값은 해당 서버에 요청 시 자동으로 담겨서 보내지게 됩니다 (개발자 도구의 Header 내부 cookie에 담겨집니다) 클라이언트에서 활용해야 한다면 cookie가 아닌 body 내부에서 받아와 사용해야 합니다.

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

AI 답변
커리어리 AI 봇 프로필 이미지

커리어리 AI 봇

GPT가 달아주는 답변입니다.

2024년 01월 23일

먼저, 생성된 JWT 토큰을 HttpOnly 쿠키에 저장하는 방식은 매우 안전한 방식이므로 좋은 선택이라고 할 수 있습니다. 하지만, 이러한 보안 조치로 인해 웹소켓에서 사용자 검증이 어려워질 수 있습니다. 웹소켓 프로토콜은 일반적인 HTTP 프로토콜과는 다르게, 헤더 값을 변경하거나 추가하는 것이 불가능합니다. 그러므로 JWT 토큰을 WebSocket 요청 헤더에 포함시키기 위해서는 WebSocket 연결을 초기화하는 Handshake 단계에서 처리해야 합니다. Spring에서 웹소켓 서버를 구현할 때 HandshakeInterceptor 인터페이스를 활용하여 Handshake 단계에서의 작업을 커스터마이징할 수 있습니다. 이를 활용하여 아래와 같은 방법으로 해결할 수 있습니다: 1. 클라이언트(React)가 처음 로그인 하여 JWT를 받았을 때, 이를 임시로 LocalStorage나 SessionStorage에 저장합니다. 2. 웹소켓 연결 시도 직전에 Storage에서 JWT를 읽어와 연결 요청 URL의 쿼리 문자열 패러미터로 전달합니다.(예: `wss://yourserver.com/chat?jwt=token`) 3. 서버에서는 HandshakeInterceptor를 사용하여 JWT 값을 얻어와 사용자를 인증합니다. 이렇게 하면, 웹소켓 연결 시 HttpOnly 쿠키에 접근할 필요 없이 User가 유효한지 검증할 수 있습니다. 이 방법은 웹소켓 통신 중 JWT 토큰을 필요로 하는 모든 요청에 재사용할 수 있습니다. 다만, 이렇게 되면 Firewall 등에서 URL에 포함된 쿼리 파라미터를 보고 판단하므로 보안상 좋지 않을 수 있으니 API Gateway 등을 사용하여 내부 네트워크에서만 해석될 수 있도록 관리해주어야 합니다. 마지막으로, 이 방법은 전체 솔루션에 영향을 미칠 수 있는 결정이므로 프로젝트 팀 멤버나 기타 관계자들과 충분히 논의해보시기 바랍니다.

목록으로

지금 가입하면 모든 질문의 답변을 볼 수 있어요!