2022.06.13 WIL - CORS & 회고록

Seong Hyeon Kim·2022년 6월 12일
0

항해99

목록 보기
14/16

CORS(Cross Origin Resource Sharing)

  • CORS 정책은 우리가 가져오는 리소스들이 안전한지 검사하는 관문이다.
    웹개발을 하는 사람들은 이 CORS 정책위반으로 인해 에러가 나는 상황을 많이들 겪어봤을것이라고 생각 된다.

'https://api.lubycon.com/me'에서 오리진 'https://localhost:3000'으로 가져올 수 있는 액세스가 CORS 정책에 의해 차단되었습니다. 요청된 리소스에 'Access-Control-Allow-Origin' 헤더가 없습니다. 불투명한 응답이 필요에 적합한 경우, 요청 모드를 '노코어'로 설정하여 CORS가 비활성화된 리소스를 가져오십시오.

이는 HTTP 요청에 대해서 어떤 요청을 하느냐에 따라 각기 다른 특징을 가지고 있기 때문이다.

  • HTML → 기본적으로 Cross-Origin 정책을 따름
    link 태그에서 다른 origin의 css 등의 리소스에 접근하는 것이 가능
    img 태그등에서 다른 리소스에 접근하는 것이 가능

XMLHttpRequest, Fetch API 등 script 태그 내 → 기본적으로 Same-Origin 정책을 따름

자바스크립트는 서로 다른 도메인에 대한 요청을 보안상 제한한다. (브라우저 기본 설정은 하나의 서버 연결만 허용)
이 정책을 Same-Origin-Policy라고 한다.

CORS (Cross-Origin Resource Sharing) <교차&다른 출처 리소스 공유>

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는,
추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제다.

즉, 위에서 시뻘겋게 CORS 어쩌구 에러는 CORS를 허용해서 아무런 탈 없이 다른 출처 리소스 공유를 해달라는 권고 사항 같은 것이라 볼 수 있다.

웹 애플리케이션은 리소스가 자신의 출처(도메인, 프로토콜, 포트)와 다를 때 교차 출처 HTTP 요청을 실행하게 된다.

CORS 기본 동작과정

  1. 클라이언트에서 HTTP요청의 헤더에 Origin을 담아 전달한다.
    다른 Origin의 리소스 요청시 클라이언트는 HTTP요청을 보낸다.
    이때 요청헤더의 Origin필드에는 요청을 보내는 Origin을 담아보낸다. 

  2. 서버는 응답헤더에 Access-Control-Allow-Origin을 담아 클라이언트로 전달한다.
    서버가 응답을 보낼때, 허락하는 Origin을 클라이언트에게 전달한다.

  3. 클라이언트에서, 자신이 보냈던 요청의 Origin과 서버가 보내준 Access-Control-Allow-Origin을 비교한다.
    자신이 보낸 Origin과 서버가 보내준 Access-Control-Allow-Origin을 비교하여 차단할지 말지를 결정한다.
    만약 유효하지 않다면 그 응답을 사용하지 않고 버린다.
    (위의 경우에는 둘다 http://localhost:3000이기 때문에 유효한 경우이다.)

CORS 해결방법 두가지

  1. Chrome 확장 프로그램 이용
    Chrome에서는 CORS 문제를 해결하기 위한 확장 프로그램을 제공해준다. 
  • 'Allow CORS: Access-Control-Allow-Origin' 을 설치 해준다.
    브라우저 오른쪽 상단에서 확장 프로그램을 활성화 시킬 수 있다. 해당 프로그램을 활성화 시키게 되면, 로컬 환경에서 API를 사용 시, CORS 문제를 해결할 수 있다.
  1. 서버에서 Access-Control-Allow-Origin 세팅하기
    가장 정석적이고 근본적인 해결책이다.
res.setHeader('Access-Control-Allow-origin', '*');
res.setHeader('Access-Control-Allow-Credentials', 'true'); // 쿠키 주고받기 허용

이때 *을 사용하면 모든 Origin에서 오는 요청을 허용한다는 의미이므로 당장은 편할 수 있겠지만, 바꿔서 생각하면 정체도 모르는 이상한 출처에서 오는 요청까지 모두 허용하기 때문에 보안은 더 허술해진다.

그러니 가급적이면 귀찮더라도 

res.setHeader('Access-Control-Allow-origin', 'https://inpa.tistory.com');

와 같이 출처를 명시해주도록 하자.

이 헤더는 Nginx나 Apache와 같은 서버 엔진의 설정에서 추가할 수도 있지만,
아무래도 복잡한 세팅을 하기는 불편하기 때문에 소스 코드 내에서 응답 미들웨어 등을 사용하여 세팅하는 것을 추천한다.

// 헤더에 작성된 출처만 브라우저가 리소스를 접근할 수 있도록 허용함.
Access-Control-Allow-Origin: <https://naver.com>
 
// 리소스 접근을 허용하는 HTTP 메서드를 지정해 주는 헤더
Access-Control-Request-Methods: GET, POST, PUT, DELETE 
 
// 서버에서 응답 헤더에 추가해 줘야 브라우저의 자바스크립트에서 헤더에 접근 허용
Access-Control-Expose-Headers: Authorization 
 
// preflight 요청 결과를 캐시 할 수 있는 시간을 나타냄.
// 60초 동안 preflight 요청을 캐시하는 설정으로, 첫 요청 이후 60초 동안은 OPTIONS 메소드를 사용하는 예비 요청을 보내지 않는다.
Access-Control-Max-Age: 60 
 
// 자바스크립트 요청에서 credentials가 include일 때 요청에 대한 응답을 할 수 있는지를 나타낸다
Access-Control-Allow-Credentials: true


Chapter 3-3에서 스스로 가장 많이 성장했다고 느낀 부분이 있다면 자유롭게 적어주세요.

  • 저작권 문제가 될수 있어서 비공개로 작성해놓앗지만 강의를 듣고 강의자료들을 정리하면서 자바스크립트에서 기초적인 부분들 그리고 나도 모르게 사용하고 있던 부분들에 대해 공부를 하면서 좀더 개념적인 부분에서 보완이 된게 이번주에서 가장 성장한 부분인것 같습니다

Chapter 3-3에서 스스로 더 많이 성장하기 위해, 어떤 노력을 더 할 수 있었을까요?

  • 자바스크립트 뿐만 아니라 노드js 나 mysql등 앞으로 사용하게 될 것을에 대해서도 좀더 공부했었으면 좋았을텐데 시간이 부족해서 못한 아쉬움이 좀 있는거 같습니다.
profile
삽질도 100번 하면 요령이 생긴다. 부족한 건 경험으로 채우는 백엔드 개발자

0개의 댓글