개발자
안녕하세요, Spring과 React를 활용하여 실시간 채팅 기능을 구현 중인 학생입니다. 현재 저희 시스템은 사용자가 로그인을 성공하면, JWT 토큰을 생성하여 이를 HttpOnly 쿠키에 저장하고 있습니다. 이후 해당 토큰을 이용해서 사용자의 인증 및 인가를 처리합니다. 그리고 웹소켓을 화룡해 채팅 기능을 구현하고 있는데, 사용자가 채팅 메시지를 웹소켓을 통해 서버로 전송할 때마다, 해당 사용자의 JWT 토큰을 검사하여 유효한 사용자인지 확인하려고 합니다. 그러나 현재 쿠키가 HttpOnly로 설정되어 있어서, React에서 쿠키에 접근할 수 없습니다. 따라서 웹소켓 메시지를 보낼 때마다 JWT 토큰을 메시지에 포함시키지 못하고 있습니다. 구글링해서 찾아보니 다른 개발자들의 경우 클라이언트에서 헤더에 토큰을 포함하여 서버로 전송하고, 서버에서는 StompHeaderAccessor의 getFirstNativeHeader 메서드를 사용하여 토큰을 받아 사용자 검증을 하는 방식을 주로 사용하는 것 같습니다. 그러나 저희 시스템에서는 이 방식을 사용할 수 없어, 다른 해결 방안을 찾고 있습니다. 현재 제가 생각한 방식은 웹소켓 연결 시 웹소켓 세션에 해당 사용자의 토큰값을 저장하여 채팅 메시지가 서버로 전송될 때마다, 웹소켓 세션에 저장된 토큰값을 검증하는 방식입니다. 만약, 이 방식을 사용한다면 사용자 토큰값의 유효 기간이 끝나면 리프래시 토큰을 사용한 사용자 토큰 재발급 방식은 사용자 웹 브라우저 쿠키에 접근하지 못하니 불가능한가요? HttpOnly 쿠키에 저장된 JWT 토큰을 웹소켓 통신에서 어떻게 활용할 수 있을지 조언해주시면 감사하겠습니다.
답변 1
지금 가입하면 모든 질문의 답변을 볼 수 있어요!
현직자들의 명쾌한 답변을 얻을 수 있어요.
이미 회원이신가요?
커리어리 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 등을 사용하여 내부 네트워크에서만 해석될 수 있도록 관리해주어야 합니다. 마지막으로, 이 방법은 전체 솔루션에 영향을 미칠 수 있는 결정이므로 프로젝트 팀 멤버나 기타 관계자들과 충분히 논의해보시기 바랍니다.
지금 가입하면 모든 질문의 답변을 볼 수 있어요!