증상
웹에서 애플 로그인을 하면 콜백 화면에 Invalid CORS request 만 뜨고 로그인이 끝나지 않는다.
원인
애플 웹 로그인은 response_mode=form_post(ADR 0023)라 콜백이 애플 도메인에서 우리 서버로 오는 크로스 사이트 POST 다. 브라우저가 Origin: https://appleid.apple.com 을 붙이는데, SecurityConfig.corsConfigurationSource() 의 CORS 규칙이 /api/** 전체에 걸려 있고 허용 Origin 은 ditto.pics·www.ditto.pics 뿐이라 거절된다.
DefaultCorsProcessor.handleInternal 은 preflight 여부와 무관하게 Origin 을 먼저 대조하고, 어긋나면 rejectRequest 로 403 + Invalid CORS request 본문을 내보낸다. 컨트롤러는 실행되지 않아 로그에도 남지 않는다.
재현 (프로덕션)
POST /api/v1/users/social-login/APPLE/callback + Origin: https://appleid.apple.com → 403 Invalid CORS request
같은 요청에서 Origin 헤더만 제거 → 200
POST /admin/oauth/apple/callback + Origin: https://appleid.apple.com → 302
어드민 콜백이 멀쩡한 건 /admin/** 이 CORS 설정에 등록돼 있지 않아서다.
이 경로에서 Origin 검사가 지키는 것이 없는 이유
- 애플 콜백은 JS 호출이 아니라 페이지 이동이라 브라우저는 CORS 를 적용하지 않는다. Spring 만 혼자 거절하는 상태다.
- 브라우저가 대신 붙여주는 인증정보를 쓰지 않는다. 쿠키를 읽지 않고
id_token 폼 값만 읽는다.
- 응답은 FE 로 보내는 302 뿐이라 읽어갈 본문이 없다.
- 실제 방어선은
AppleIdTokenVerifier 의 서명·iss·aud·exp 검증이다. Origin 헤더는 위조할 수 있지만 애플 서명은 위조할 수 없다.
할 일
범위 밖
refreshToken 쿠키의 SameSite=Lax 가 크로스 사이트 POST 응답에서 무시될 가능성이 있으나 미확인이다. 이 수정을 배포한 뒤 실제 브라우저로 확인하고, 문제면 별도 이슈로 분리한다.
증상
웹에서 애플 로그인을 하면 콜백 화면에
Invalid CORS request만 뜨고 로그인이 끝나지 않는다.원인
애플 웹 로그인은
response_mode=form_post(ADR 0023)라 콜백이 애플 도메인에서 우리 서버로 오는 크로스 사이트 POST 다. 브라우저가Origin: https://appleid.apple.com을 붙이는데,SecurityConfig.corsConfigurationSource()의 CORS 규칙이/api/**전체에 걸려 있고 허용 Origin 은ditto.pics·www.ditto.pics뿐이라 거절된다.DefaultCorsProcessor.handleInternal은 preflight 여부와 무관하게 Origin 을 먼저 대조하고, 어긋나면rejectRequest로 403 +Invalid CORS request본문을 내보낸다. 컨트롤러는 실행되지 않아 로그에도 남지 않는다.재현 (프로덕션)
어드민 콜백이 멀쩡한 건
/admin/**이 CORS 설정에 등록돼 있지 않아서다.이 경로에서 Origin 검사가 지키는 것이 없는 이유
id_token폼 값만 읽는다.AppleIdTokenVerifier의 서명·iss·aud·exp검증이다. Origin 헤더는 위조할 수 있지만 애플 서명은 위조할 수 없다.할 일
UrlBasedCorsConfigurationSource에 애플 콜백 경로를/api/**보다 먼저 등록하고, 그 경로만 Origin 을 가리지 않게 한다 (allowedOrigins = "*",allowCredentials = false)SecurityConfigTest에 회귀 테스트 추가 — 애플 콜백은 외부 Origin POST 통과, 다른 API 는 여전히 차단범위 밖
refreshToken쿠키의SameSite=Lax가 크로스 사이트 POST 응답에서 무시될 가능성이 있으나 미확인이다. 이 수정을 배포한 뒤 실제 브라우저로 확인하고, 문제면 별도 이슈로 분리한다.