Web SERVER _CORS

이유정·2022년 10월 16일
0

코드스테이츠 TIL

목록 보기
32/62

CORS에러가 뜨는 것을 경험하게 될 것이다.
CORS를 알아보기 전에, CORS가 필요하게 된 배경인 SOP먼저 알아보자!

Chapter1-1. SOP

SOP (Same-Origin Policy)
: 동일 출처 정책
: 같은 출처의 리소스만 공유가 가능하다.

여기서, '출처(Origin)'은 다음과 같다.

출처는 프로토콜, 호스트, 포트의 조합이다. 이 모든게 다 같아야 같은 출처로 취급한다.

예)

https://www.codestates.com vs http://www.codestates.com
⇒ 두 URI는 프로토콜이 다르기 때문에 동일 출처가 아닙니다. ( https / http )
https://urclass.codestates.com vs https://codestates.com
⇒ 두 URI는 호스트가 다르기 때문에 동일 출처가 아닙니다. ( urclass.codestates.com / codestates.com )
http://codestates.com:81 vs http://codestates.com
http 프로토콜의 기본 포트는 80입니다. 따라서 http://codestates.com 는 http://codestates.com:80 과 동일합니다.
⇒ 두 URI는 포트가 다르기 때문에 동일 출처가 아닙니다. ( :81 / :80 )
https://codestates.com:443 vs https://codestates.com
https 프로토콜의 기본 포트는 443입니다. 따라서 https://codestates.com 는 https://codestates.com:443 과 동일합니다.
⇒ 두 URI는 프로토콜, 호스트, 포트가 모두 같은 동일 출처입니다.

SOP은 왜 있는걸까?

  • 동일 출처 정책은 해로울 수 있는 문서를 분리해서 공격받을 수 있는 수를 줄임
  • 애초에 다른 사이트와의 리소스 공유를 제한해, 네이버 로그인 정보가 타 사이트의 코드에 의해 새어나가는 것을 방지한다.
  • 모든 브라우저는 기본적으로 SOP 정책을 사용한다.

그러나, 다른 출처의 리소스를 사용하게 될 일은 왕많다.

  • 로컬환경에서 개발할 때 클라이언트와 서버를 따로 개발하면 출처 다름
  • 네이버 지도 API를 사용하고 싶다면?
  • github 정보를 받아오고 싶다면?

Chapter1-2. CORS

위 문제에서 필요한 것이 CORS다.
: Cross-Origin Resouce Sharing
: 교차 출처 리소스 공유

  • 추가 HTTP헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한('Access-Control-Allow-Origin')을 부여하도록 브라우저에 알려주는 체제다.

즉, 정리하자면 사실 이 에러는 SOP때문이고, 해결할 수 있는 방안이 CORS인 것!

Chapter1-3. CORS 동작 방식

CORS 동작 방식은 3가지가 있다.
1) 프리플라이트 요청 (Preflight Request)

  • 실제 요청을 보내기전에 OPTIONS메서드로 사전요청을 보내, 해당 출처 리소스에 접근 권한이 있는지 확인하는 것
  • 브라우저는 서버에 실제 요청을 보내기 전에 프리플라이트 요청을 보내고, 응답 헤더의 Access-Control-Allow-Origin 으로 요청을 보낸 출처가 돌아오면 실제 요청을 보낸다 !
    만약, 요청을 보낸 출처가 접근 권한이 없다면 브라우저에서 CORS 에러를 띄우게 되거, 실제 요청을 전달되지 않는다.
  • 왜 필요할까? => 실제 요청을 보내기 전에 미리 권한을 확인해, 리소스 측면에서 효율적이다. => CORS에 대비가 안된 서버를 보호할 수 있다.

2) 단순 요청 (Simple Request)

  • 특정 조건이 만족되면 프리플라이트 요청을 생략하고 요청을 보내는 것으로, 이 조건들을 모두 만족시키긴 어렵다... 일단 참고만 하자!

  • 조건들: GET, HEAD, POST 요청 중 하나여야 합니다.
    자동으로 설정되는 헤더 외에, Accept, Accept-Language, Content-Language, Content-Type 헤더의 값만 수동으로 설정할 수 있습니다.
    Content-Type 헤더에는 application/x-www-form-urlencoded, multipart/form-data, text/plain 값만 허용됩니다.

3) 인증정보를 포함한 요청 (Credentialed Request)

  • 요청 헤더에 인증 정보를 담아 보내는 요청이다. 출처가 다를 경우엔 별도의 설정을 해야, 쿠키를 보낼 수 있다. (프론트, 서버 모두 CORS 설정이 필요)
  • 프론트 측에서는 요청 헤더에 withCredentials : true 를 넣어줘야 한다.
    서버 측에서는 응답 헤더에 Access-Control-Allow-Credentials : true 를 넣어줘야 한다.
    서버 측에서 Access-Control-Allow-Origin 을 설정할 때, 모든 출처를 허용한다는 뜻의 와일드카드(*)로 설정하면 에러가 발생. 인증 정보를 다루는 만큼 출처를 정확하게 설정!

Chapter1-4. CORS 설정 방법

1) Node.js 서버

const http = require('http')

const server = http.createrServer((request, response)=>{
  // 모든 도메인
  response.setHeader("Access-Control-Allow-Origin", "*");
  // 특정 도메인 
  response.setHeader("Access-Control-Allow-Origin", "https://naver.com");
  // 인증 정보를 포함한 요청을 받을 경우 
  response.setHeader("Access-Control-Allow-Credential", "true");
 })

2) Express 서버

const cors = require("cors")
const app = require("app")

//모든 도메인
app.use(cors());

//특정 도메인 
const options = {
  origin : "http://naver.com", //접근 권한을 부여하는 도메인
  credentials: true; 
  optionSuccessStatus: 200,
};
app.use(options())

//특정 요청
app.get("/example/:id",cors(), function(req,res,next){
 res.json({msg: "example"});
})

이 외 다양한 개발 환경에서도, 헤더의 값을 설정하는 방법만 알면 CORS 설정을 해줄 수 있다.

profile
팀에 기여하고, 개발자 생태계에 기여하는 엔지니어로

0개의 댓글