CORS 오류는 무엇입니까? 어떻게 하면 해결할까?

소개



여러분이 브라우저에서 API를 실행할 때 다음과 같은 오류가 발생한 적이 있습니까?
Access to XMLHttpRequest at 'http://localhost:3065/user' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

이것은 CORS라고 하는 정책에 의한 에러입니다만, 스스로도 몇번이 이 에러에 발생한 적은 있었습니다만, 깊게 이해하고 있지 않고, 어쩐지 해결하고 있었습니다.
이번에는 실제로 CORS에 대해 해설과 해결 방법에 대해 실연을 나누면서 기사로 해 나가고 싶습니다.

원래 CORS 란 무엇입니까?



브라우저는 SORS(Same-Origin Resource shareing)라는 구조를 구현하고 있으며, 다른 오리진(Cross-origin)간에 리소스에 대한 액세스를 제한하고 있습니다.
왜 제한하고 있는가 하면, 크로스 사이트 서젤리 등의 보안 공격을 방지하기 위해서입니다.
그리고, CORS(Cross-origin resource sharing)가 무엇인가라고 하면, 이 SORS의 제약을 일부 해제하는 것으로 다른 오리진에의 자원의 액세스를 허가한 것입니다.

CORS 오류를 발생시킵니다.



실험 환경 구축 절차



이번 환경은
http://localhost:8100 (이후, A로 한다)의 웹 페이지로부터 test라고 하는 버튼을 클릭하면(자)
A라는 오리진에서,
http://localhost:8030 (이후, B라고 한다)라고 하는 다른 오리진에 액세스 해, 액세스에 성공하면 backend라고 하는 캐릭터 라인을 표시시키기 위한 것이 됩니다.


  • git 저장소를 clone
  • $ git clone https://github.com/hgaiji/CORS-test
    
  • 컨테이너 환경 시작
  • $ docker-compose up -d
    
  • A에 브라우저에서 액세스

  • 아래와 같은 화면이 표시되고 있을까 생각합니다.

  • 개발자 콘솔 열기

  • 웹 페이지로 이동한 후 개발자 콘솔로 이동하여 콘솔 탭을 엽니다.
  • 액세스 해 보자

  • 앞서 설명한 대로 다른 오리진에 액세스하려고 하기 때문에 CORS 오류가 발생합니다.

    실제로 A( http://localhost:8100 ) 에서 B( http://localhost:8030 ) 에 액세스하여 CORS 오류가 발생하는지 확인합니다.

    그러면 개발자 콘솔의 console 탭에 다음과 같은 오류가 발생하고 backend라는 문자열이 표시되지 않았는지 생각합니다.
    Access to XMLHttpRequest at 'http://localhost:8030/' from origin 'http://localhost:8100' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
    

    이것은 CORS 오류입니다!

    CORS의 작동 방식 (CORS 설정)



    http://localhost:8100 에서 http://localhost:8070 에 리퀘스트할 때는 리퀘스트 헤더에 origin: http://localhost:8100 가 부여됩니다. (developer 도구의 header 탭에서 확인할 수 있습니다.)

    http://localhost:8070 측에서, http://localhost:8100 에의 액세스를 허가하는 경우 (CORS 의 설정), 아래와 같이 리스폰스 헤더를 부여하도록(듯이) 설정합니다.
    Access-Control-Allow-Origin: http://localhost:8100
    

    실제로 설정해 보겠습니다.
    app.go에 다음 설정을 추가해 봅시다.

    app.go
    // test
    func test(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "application/json")
        w.Header().Set("Access-Control-Allow-Origin", "http://localhost:8100")
        w.Write([]byte("backend"))
    }
    

    여기에서 test 버튼을 클릭하면 무사히 액세스할 수 있었습니다.

    요약


  • CORS
  • 브라우저 정책에서 다른 오리진에 대한 액세스를 허용하는 것

  • CORS 오류 해결 방법
  • 액세스 받는 쪽 (서버 측) 응답 헤더에 Access-Control-Allow-Origin 헤더를 부여하는 설정을 추가합니다.

  • 좋은 웹페이지 즐겨찾기