spring_2기[본캠프]/과제

[과제] Spring 플러스 프로젝트 Day 11

minwoo95 2026. 3. 24. 21:11

https://github.com/TheOne-team-1/TheOne-Bottle-Shop

 

GitHub - TheOne-team-1/TheOne-Bottle-Shop: 주류 커머스 플랫폼 백엔드 구현하기

주류 커머스 플랫폼 백엔드 구현하기. Contribute to TheOne-team-1/TheOne-Bottle-Shop development by creating an account on GitHub.

github.com

The One PPT.pptx
12.85MB

 

상황: 소셜 로그인(OAuth2) 사용자가 채팅 서비스 진입 시, JWT 토큰 불일치로 인해 웹소켓 연결(CONNECT)이 거부되는 현상 발생.

작업 중 난관: 로컬에서 보안 로직(핸들러, 인터셉터)을 수정하던 중, 팀 원격 저장소(dev)에 대규모 채팅 도메인 업데이트가 반영되어 소스 코드 충돌 및 환경 변화(Testcontainers 도입)에 직면함.

트러블슈팅: Git 협업 및 코드 통합
1. 충돌(Conflict) 상황의 재구성과 원인 분석
문제: git pull 시 로컬 작업물과 원격의 변경 사항이 동일 파일(OAuth2SuccessHandler)에서 충돌.

원인: 팀원들이 V1 배포를 위해 전체 히스토리를 정리하면서 파일 구조와 설정(yml)을 대대적으로 수정함. 로컬의 stash와 원격의 fetch 데이터가 엉키며 복합 충돌 발생.

2. 전략적 해결: Commit & Merge 방식 채택
선택: 단순 stash pop은 충돌 해결 시 작업 이력을 잃을 위험이 큼. 따라서 현재 로컬 상태를 임시 커밋으로 박제한 뒤 머지하는 방식을 선택.

과정:

로컬 작업 보존: git add . -> git commit (작업 중간 지점 스냅샷).

원격 이력 병합: git fetch origin -> git merge origin/dev.

자동 병합 활용: ort 전략을 통해 파일 위치가 바뀐 채팅 도메인 코드를 내 로컬의 보안 설정 로직과 안전하게 통합.

교훈: 협업 시 대규모 업데이트가 있을 때는 stash보다 commit 기반의 머지가 히스토리 추적과 복구 면에서 훨씬 안전함.

기술적 해결: 소셜 로그인 사용자를 위한 채팅 인증 아키텍처
1. JwtProvider 로직의 단일화
기존 문제: 일반 로그인과 소셜 로그인의 사용자 정보 추출 방식이 달라 토큰 발급 시 클레임(Claims) 정보가 누락됨.

해결: OAuth2User와 일반 UserDetails를 공통으로 아우르는 DTO를 거쳐 JWT를 생성하도록 로직을 일원화하여 채팅 서비스에서 동일한 토큰 검증이 가능하도록 개선.

2. StompAuthChannelInterceptor를 통한 권한 주입
이슈: 웹소켓은 HTTP와 달리 한 번 연결되면 상태가 유지되지만, 최초 연결(CONNECT) 시 보안 검증이 필수적임.

구현:

ChannelInterceptor의 preSend 메서드를 오버라이드.

헤더의 Authorization: Bearer <Token>을 파싱.

JwtProvider로 검증 후 UsernamePasswordAuthenticationToken을 생성하여 세션에 권한 주입.

결과: 소셜 로그인 유저도 끊김 없이 실시간 채팅 서비스 이용 가능.

3. 리다이렉트 핸들러 최적화
조치: OAuth2SuccessHandler에서 토큰 발급 후 프론트엔드 확인용 페이지(page.html)로 쿼리 파라미터를 통해 JWT를 전달.

의의: 클라이언트 측에서 토큰을 수신하여 localStorage 등에 저장하고 웹소켓 연결 시 헤더에 실어 보낼 수 있는 기반 마련.

인사이트
테스트 환경의 독립성 (No Docker Strategy):
팀원들이 도입한 Testcontainers는 로컬에 도커가 없을 경우 전체 빌드를 방해함. 이를 해결하기 위해 @Mock 기반의 단위 테스트를 작성하여 인프라 의존성을 제거하고 비즈니스 로직의 순수성을 검증함. 커버리지 100%를 달성하기 위해서는 이러한 단위 테스트 위주의 설계가 필수적임을 체감함.

CI/CD 파이프라인 고려:
푸시(Push) 후 GitHub Actions의 동작 방식을 고려하여, 빌드가 깨지지 않도록 로컬에서 clean build -x test로 사전 검증을 마침.

엔티티와 DTO의 분리:
채팅 메시지 전송 시 유저 정보를 안전하게 다루기 위해 엔티티 직접 참조 대신 DTO를 통한 데이터 전달 방식을 강화함.