Skip to content

fix : 약속 상태 자동 전환 및 인증 실패 시 CORS 에러 해결#49

Merged
ThreeeJ merged 2 commits into
mainfrom
fix/#11
May 12, 2026
Merged

fix : 약속 상태 자동 전환 및 인증 실패 시 CORS 에러 해결#49
ThreeeJ merged 2 commits into
mainfrom
fix/#11

Conversation

@ThreeeJ

@ThreeeJ ThreeeJ commented May 12, 2026

Copy link
Copy Markdown
Contributor

🔍 관련 이슈


✅ 작업 분류

  • 버그 수정
  • 신규 기능
  • 프로젝트 구조 변경
  • 코드 리팩토링
  • 기능 수정

✨ 작업 내용

  • 약속 상태 자동 전환 로직 추가
  • 토큰 만료 시 CORS 에러 발생 문제 해결
    • SecurityConfig에 .cors(Customizer.withDefaults()) 추가
    • Spring Security 필터 체인 맨 앞에 CorsFilter 자동 등록

👥 전달사항


✅ 체크리스트

  • 코드가 컴파일 및 빌드됨
  • 모든 테스트가 통과함
  • 관련 문서가 업데이트됨
  • 커밋 메시지를 확인함

📸 스크린샷


💡 배운 것 / 시도한 것 / 고민한 점

문제 상황

  • 토큰 만료 시 네트워크 탭엔 401, 콘솔엔 CORS 에러가 동시에 뜸
  • 프론트에서 401을 못 읽고 토큰 재발급 로직이 안 돌아감

원인

  • WebMvcConfigurer.addCorsMappings는 MVC HandlerMapping의 interceptor
  • Security 필터에서 인증 실패로 응답이 끊기면 MVC까지 도달 못 함
  • 즉, CORS 헤더가 붙기 전에 응답이 나가버림

해결 방안

  • SecurityConfigSecurityFilterChainhttp.cors(Customizer.withDefaults()) 한 줄 추가

동작 흐름

  1. 요청 진입 → Security 필터 체인 맨 앞 CorsFilter 실행
  2. CorsFilter가 사용할 CorsConfigurationSource 빈 탐색 → 없음
  3. 폴백으로 HandlerMappingIntrospector를 통해 MVC의 addCorsMappings 설정을 읽어옴
  4. 읽어온 설정으로 응답에 CORS 헤더 세팅
  5. 이후 Security 필터들이 인증 검사 진행
    → 실패해도 헤더는 이미 붙어있는 상태로 응답
    → 401/403 응답에도 CORS 헤더 정상 포함

보안 영향

  • 허용 origin 목록(localhost:5173, netlify, vercel) 변경 없음 → 허용된 곳만 허용, 차단된 곳은 그대로 차단
  • 변경된 건 "차단/허용 정책"이 아니라 CORS 검사 시점: MVC 진입 후 → Security 진입 전으로 앞당겨짐
  • 결과적으로 인증 실패 응답에도 CORS 헤더가 붙어, 프론트가 정상적으로 status code를 읽을 수 있게 됨

@ThreeeJ ThreeeJ self-assigned this May 12, 2026
@ThreeeJ ThreeeJ added the bug Something isn't working label May 12, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces state management for promises, transitioning their status between 'PENDING' and 'PROCEEDING' as candidates are added or removed. It also enables default CORS settings in the security configuration. Feedback was provided to ensure that the promise status only considers active candidates when determining if it should revert to 'PENDING', preventing incorrect state transitions when inactive candidates exist.


Optional<Candidate> findByIdAndPromiseId(Long candidateId, Long promiseId);

long countByPromiseId(Long promiseId);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

재투표 등으로 인해 비활성화된(inactive) 후보지가 남아있는 경우에도, 활성 후보지가 없다면 약속 상태를 '장소 미정(PENDING)'으로 전환하는 것이 비즈니스 로직상 더 적절합니다. 따라서 단순히 전체 개수를 세는 countByPromiseId 대신 활성 상태인 후보지만 카운트하는 메서드를 사용하는 것을 권장합니다.

Suggested change
long countByPromiseId(Long promiseId);
long countByPromiseIdAndIsActiveTrue(Long promiseId);

Comment on lines +113 to +114
// 마지막 후보지 삭제 시 약속 상태를 다시 장소 미정으로 되돌림
if (candidateRepository.countByPromiseId(promiseId) == 0) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

비활성화된 후보지가 존재하더라도 활성화된 후보지가 모두 삭제되었다면 약속 상태를 '장소 미정(PENDING)'으로 되돌려야 합니다. 앞서 CandidateRepository에 제안한 countByPromiseIdAndIsActiveTrue 메서드를 사용하여 활성 후보지 존재 여부를 체크하도록 수정하는 것이 좋습니다.

Suggested change
// 마지막 후보지 삭제 시 약속 상태를 다시 장소 미정으로 되돌림
if (candidateRepository.countByPromiseId(promiseId) == 0) {
// 마지막 활성 후보지 삭제 시 약속 상태를 다시 장소 미정으로 되돌림
if (candidateRepository.countByPromiseIdAndIsActiveTrue(promiseId) == 0) {

@ThreeeJ ThreeeJ merged commit 5348ec1 into main May 12, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant