본문 바로가기

Web/Spring

[CORS] Spring Security에서 Preflight CORS 문제 해결하기

문제 상황

1
2
3
4
5
6
@RestController
@RequestMapping("/members")
@CrossOrigin(origins = "*")
public class MemberController {
    // ...
}
cs

Controller의 어노테이션으로 @CrossOrigin를 달아서 잘 작동하던 Controller가 CORS에러를 뿜기 시작했다.

해석해 보면 preflight요청이 Access-Control-Allow-Origin 헤더가 없어서 통과하지 못했다는 것이다.

여기서 Preflight가 무엇인지부터 알아보자.

1. Preflight란 무엇인가?

CORS의 사전 작업으로 Chrome과 같은 브라우저에서 HTTP Method "OPTIONS" Request로 서버측에 먼저 확인하는 방법이다.

 

일반적으로 Preflight가 필요한 경우 브라우저에서 자동 발생한다. 

CORS 명세에는 브라우저가 HTTP Method "OPTIONS"로  이 preflight를 통해 서버의 허가가 떨어져야 실제 요청을 보낼 수 있다.

 

Simple Request

CORS preflight를 이용하지 않는 요청을 MDN에서는 Simple Request라고 한다.

Simple Request는 다음 조건을 모두 충족하는 Request이다.

  • 다음 중 하나의 Method여야 한다.
    • GET
    • HEAD
    • POST
  • 자동으로 설정되는 Header ( Ex. Content-Type, User-Agent, https://fetch.spec.whatwg.org/#forbidden-header-name 에 있는 Header 등.. ) 와 수동 설정 Header Fetch 명세에서 정의한 CORS용 Header ( Content-Type, Accept, Accept-Language, Content-Language ) 만이 허용된다.
  • Content-Type은 다음 값들만 허용된다.
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain
  • XMLHtppRequestUpload 객체에 Event Listener가 등록되어 있지 않아야한다.
  • ReadableStream 객체가 요청에 사용되지 않아야한다.

Preflight Request

위의 Simple Request와 달리 HTTP Method "OPTIONS"를 통해 먼저 Request를 보내 실제 Request 전에 안전한지 확인한다.

 

 

 

WebMvcConfigure 설정으로 해결

 


References

https://developer.mozilla.org/ko/docs/Glossary/Preflight_request

https://developer.mozilla.org/ko/docs/Web/HTTP/CORS