Post

CORS에 대한 사실과 오해

CORS에 대한 사실과 오해

사실 아무도 오해한 적 없다. 지금 진행하는 프로젝트에서 CORS 설정을 해야 하는 일이 있어 겸사겸사 정리해 본다.

도메인만 동일하면 같은 출처(Same Origin)이다.

  • 아니다.
  • Protocol, Host, Port를 통해서 동일한 출처(Same Origin)인지 아닌지를 판단한다.
  • 즉, 3가지(https://, yunjaejjang.com, :443) 모두 동일해야지 동일 출처이다.

출처가 다른 경우에는 항상 preflight 요청을 보낸다.

  • 아니다.
  • cors를 조금이라도 공부해 본 사람이라면 preflight 보내고 실제 요청(내가 진짜 보내려고 하는 요청)을 보낸다고 어렴풋이 기억하고 있을 수 있다. 하지만 항상 preflight 요청을 보내는 것은 아니다. simpleRequest라고 특정 조건을 요청하면 즉시 서버로 요청을 보낼 수 있다.

  • Preflight : OPTIONS 메서드를 통해 다른 도메인의 리소스에 요청이 가능한지 확인 작업
  • 클라이언트는 preflight request를 먼저 보낸 후에 actual request를 보낸다. cors_delete
  • preflight를 보내는 과정에서 CORS error가 발생하면 클라이언트는 actual request(실제 보내려고 한 요청)를 보내지 않는다.

  • SimpleRequest: preflight 요청 없이 바로 요청을 보내는 방식
    • Some requests don’t trigger a CORS preflight.
    • 그 some requests는 다음과 같은 조건을 만족해야한다.
      • GET, POST, HEAD 중 하나의 메서드
      • 헤더로 Accept, Accept Language, Content-Language, Content-Type,,,
      • Content Type :
        • application/x-www-form-urlencoded
        • multipart/form-data
        • text/plain

    cors_get

cors의 경우에는 브라우저 정책이다.

  • 맞다. 아주 정확하다.
  • CORS는 “다른 출처의 웹페이지 JS가 응답을 읽는 것”을 제한하는 브라우저 보안 정책이다. 따라서 CORS 설정이 되어 있지 않아도(CORS에 오류가 발생하더라도) 서버에서는 정상적인 비즈니스 로직이 수행된다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    @RestController
    @RequestMapping("/api/cors")
    @RequiredArgsConstructor
    public class CorsTestController {
        
      private final CorsService corsService;
    
      @GetMapping
      public ResponseEntity<String> getMethod(){
          
        String getMethod = "get";
        long cnt = corsService.countDomain();
        System.out.println("getMethod = " + getMethod);
        System.out.println(String.format("business logic - count =  %d" , cnt));
        return ResponseEntity.ok(getMethod);
      }
    
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    @Service
    @Transactional
    @RequiredArgsConstructor
    
    public class CorsService {
    
      private final CorsRepository corsRepository;
        
      public long countDomain(){
        return corsRepository.count();
      }
    }
    

    cors_get cors_get

    CORS Error가 발생했음에도 controller에서 일어나는 로직이 모두 수행되었음을 알 수 있다.

참고 자료
[10분 테코톡] 🌳 나봄의 CORS
Cross-Origin Resource Sharing (CORS)

This post is licensed under CC BY 4.0 by the author.