프로젝트를 진행하면서 CORS 오류가 진짜 많이 발생했다. 로컬에서는 당연히 상관없었고, 클라우드 환경에 배포하고 나서부터 생긴 건데 하나 해결하면 다른 부분이 또 원인이 되어 발생하고 정말 끝이 없었다. 그런데 대부분은 원인이 그나마 확실해서 시간이 좀 걸리더라도 해결할 수 있었는데 이번에 만난 오류는 로그도 안 뜨고 원인 파악이 안 돼서 곤란했다.
지금껏 겪은 대부분의 CORS 오류의 원인은 다음과 같다.
지금까지 겪은 CORS 에러들
JWT를 쿠키로 저장하고 백엔드로 요청마다 쿠키를 포함시켜 보내지만 쿠키가 제대로 전달되지 않아서 Gateway 필터에서 막힘
이건 프론트에서도 수정을 해주어야 한다.
https://megamaker.tistory.com/328
프론트에서 쿠키를 사용 시 withCredentials 또는 credential 포함시켜야 하는 이유
쿠키 때문에 정말 많은 고생을 했다. 어찌어찌 해결이 된 듯싶었으나 프론트를 앱 엔진에 배포해서 테스트해 보니 또 쿠키 관련 문제와 CORS 문제가 발생했다. CORS는 이미 조치를 취해두었으니 이
megamaker.tistory.com
요청 헤더 허용을 안 함
Gateway CORS 설정에서 allowedHeaders: "*" 를 추가해서 요청의 특정 헤더 또는 모든 헤더를 허용해야 한다.
응답 헤더 노출 설정 안 함
응답 헤더에 커스텀 헤더를 포함시켜 보냈는데 프론트에서 응답 헤더를 확인해 보면 기본 헤더 4개밖에 없다.
exposedHeaders:
- Auth
위 처럼 응답으로 노출할 헤더를 설정해야 제대로 헤더를 받아올 수 있다.
HTTP 메서드 허용 안 되어 있음
그냥 해당 메서드 허용하면 된다.
Gateway에서 CORS 설정을 해놓고 다른 서비스에서도 CORS 설정을 해놓음
둘 다 되어 있으면 분명 뭔가가 꼬일 위험이 있다. 나도 Gateway에서는 잘 통과됐으나 로그인 서비스에서 CORS를 추가로 설정해 놓는 바람에 에러가 발생했었다. 어차피 모든 요청은 Gateway를 통과할 테니 이 부분에만 CORS 설정을 해놓았다.

spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowedOrigins:
- "http://localhost:3000" # 개발용
- "http://delibird.store"
allow-credentials: true
allowedHeaders: "*"
allowedMethods:
- GET
- POST
- PUT
- PATCH
- DELETE
- OPTIONS
exposedHeaders: # 노출할 응답 헤더 추가
- Auth
위 원인들을 모두 해결해서 적용하면 위 처럼 된다.
새로 겪은 에러...
이번에 겪은 에러는 새로웠다. 로그를 봐도 Gateway 필터를 거치지 않는지 아무것도 뜨지 않았고, 정상적인 요청은 제대로 로그가 떴다. 그래서 한참 고민해봤는데 해당 필터에서 반응이 없는 것을 보니 그전에 CORS 오류로 아예 요청이 막혀서 제대로 전달되지 않는 것 같았다. 크롬 개발자 도구로 확인해 봤는데 Preflight 요청과 원래의 요청이 같이 차단된 것을 알 수 있었다. Preflight로 본 요청을 보내기 전에 미리 OPTIONS 메서드로 요청을 한번 보내서 서버의 설정을 확인하는데 이 Preflight 요청 자체가 막혀서 본 요청도 차단된 것 같았다.
그래서 이것저것 해 본 결과 해결책을 찾았다..!
해결 방법
https://cloud.spring.io/spring-cloud-static/Greenwich.SR3/multi/multi__cors_configuration.html
118. CORS Configuration
The gateway can be configured to control CORS behavior. The "global" CORS configuration is a map of URL patterns to Spring Framework CorsConfiguration. application.yml. spring: cloud: gateway: globalcors: corsConfigurations: '[/**]': allowedOrigins: "htt
cloud.spring.io
Spring Cloud Gateway CORS 설정 공식 문서인데 여기서 이런 부분이 있다.

특정 경로에 다뤄지지 않는 부분에도 설정이 적용될 수 있도록 해당 설정을 추가하라는 것이다. Preflight는 요청이 제대로 설정을 거치지 않을 수 있기 때문이다.
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowedOrigins:
- "http://localhost:3000" # 개발용
- "http://delibird.store"
allow-credentials: true
allowedHeaders: "*"
allowedMethods:
- GET
- POST
- PUT
- PATCH
- DELETE
- OPTIONS
exposedHeaders: # 노출할 응답 헤더 추가
- Auth
add-to-simple-url-handler-mapping: true # 이 부분 추가
그래서 해당 설정을 적용했더니 이제 정상적으로 동작했다.
이제 거의 해결된 것 같으니 다른 부분에 집중할 수 있을 것 같다...
'공부 > Spring Cloud' 카테고리의 다른 글
| [Spring Cloud][GCP] NGINX로 리버스 프록시 구현하기 (0) | 2024.06.24 |
|---|---|
| [Spring Cloud][GCP] Gateway에서 HTTPS 사용하기 (pem -> p12) (0) | 2024.06.23 |
| [Spring Cloud] EC2에서 Docker Kafka 에러 해결하기 (0) | 2024.05.13 |
| [Spring Cloud][7] config-service 추가 및 설정 대칭키 암호화 (0) | 2024.05.10 |
| [Spring Cloud][6] Store 마이크로 서비스 구현하기 1 (0) | 2024.05.06 |