[Network] CORS와 SOP
2022.12.08
💡 CORS와 SOP
새로 배우는 개념인 CORS와 SOP
프론트에서도 기본적인 서버 관련 공부를 꼭 해야한다는 건 이제 누구나 아는 사실이다.
콘솔창에서 다음과 같은 에러를 종종 보고는 한다. 이 에러가 바로 CORS에러로 CORS가 필요하게 된 배경인 SOP에 대해 알아둘 필요가 있다.
📌 SOP
SOP은 Same-Origin Policy의 줄임말로, 동일 출처 정책을 뜻한다.
즉 같은 출처의 리소스만 공유가 가능하다라는 뜻인데 여기서 말하는 출처는 다음과 같다.
출처는 프로토콜, 호스트, 포트의 조합으로 되어있습니다. 이 중 하나라도 다르면 동일한 출처로 보지 않는다.
예시를 들자면
-
https://www.codestates.com
vshttp://www.codestates.com
⇒ 두 URI는 프로토콜이 다르기 때문에 동일 출처 ❌ ( https / http ) -
https://urclass.codestates.com
vshttps://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
vshttps://codestates.com
https 프로토콜의 기본 포트는 443이다. 따라서
https://codestates.com
는https://codestates.com:443
과 동일하다. ⇒ 두 URI는 프로토콜, 호스트, 포트가 모두 같은 동일 출처🙆♂️
🧐 그렇다면 왜? SOP은 생겨난걸까?
동일 출처 정책은 잠재적으로 해로울 수 있는 문서를 분리함으로써 공격받을 수 있는 경로를 줄여준다.
다른 사이트와의 리소스 공유를 제한하기 때문에 로그인 정보와 같이 민감한 정보가 타사이트의 코드에 의하여 새어나가는 것을 방지할 수 있다.
하지만 현실에서는 다른 출처의 리소스를 사용해야 할 일이 굉장히 많다. 그렇다면 어떻게 다른 출처의 리소스를 받아올 수 있는 걸까? 그 답은 바로 아래에 있다.
📌 CORS
CORS는 Cross-Origin Resource Sharing의 줄임말로 교차 출처 리소스 공유를 뜻한다.
브라우저는 SOP에 의해 기본적으로 다른 출처의 리소스 공유를 막지만, CORS를 사용하면 접근 권한을 얻을 수 있게 되는 것이다.
Request 요청 - GET, POST, PUT, PATCH, DELETE, OPTIONS, URL( /upper, /lower )… && 헤더 바디
GET은 서버의 리소스에서 데이터를 요청할 때, POST는 서버의 리소스를 새로 생성할 때, PUT & PATCH는 업데이트할 때
Response - 200 400 … && 헤더 바디
👨🏻💻 CORS의 동작 방식
CORS의 동작 방식은 크게 3가지가 있는데
- 프리플라이트 요청 ( Preflight Request )
실제 요청을 보내기 전 OPTIONS 메서드로 사전요청을 보내서 접근 권한이 있는지 확인하는 방법이다. => 처음부터 통째로 요청을 보내는 것보다 효율적
- 단순 요청 ( Simple Request )
특정 조건만 만족되면 프리플라이트 요청을 생략하고 요청을 바로 보내는 것
- 인증 정보를 포함한 요청
요청 헤더에 인증 정보를 담아 보내는 요청, 출처가 다를 경우에는 별도의 설정을 하지 않으면 쿠키를 보낼 수 없다( 민감한 정보이기 때문 ) 이 경우에는 프론트, 서버 양측 모두 CORS 설정이 필요
- 프론트 측에서는 요청 헤더에
withCredentials : true
를 - 서버 측에서는 응답 헤더에
Access-Control-Allow-Credentials : true
를 넣어줘야 한다. - 서버 측에서
Access-Control-Allow-Origin
을 설정할 때, 모든 출처를 허용한다는 뜻의 와일드카드(*)로 설정하면 에러가 발생한다. 인증 정보를 다루는 만큼 출처를 정확하게 설정해주어야 한다.
👨🏻💻 CORS의 설정 방법
-
Node.js 서버
Node.js로 간단한 HTTP 서버를 만들 경우 다음과 같이 응답 헤더를 설정해 줄 수 있다.
const http = require('http'); const server = http.createServer((request, response) => { // 모든 도메인 response.setHeader("Access-Control-Allow-Origin", "*"); // 특정 도메인 response.setHeader("Access-Control-Allow-Origin", "https://codestates.com"); // 인증 정보를 포함한 요청을 받을 경우 response.setHeader("Access-Control-Allow-Credentials", "true"); })
-
Express 서버
Express 프레임워크를 사용해서 서버를 만드는 경우 CORS 미들웨어를 사용해서 보다 간단하게 CORS 설정을 해줄 수 있다.
const cors = require("cors"); const app = express(); //모든 도메인 app.use(cors()); //특정 도메인 const options = { origin: "https://codestates.com", // 접근 권한을 부여하는 도메인 credentials: true, // 응답 헤더에 Access-Control-Allow-Credentials 추가 optionsSuccessStatus: 200, // 응답 상태 200으로 설정 }; app.use(cors(options)); //특정 요청 app.get("/example/:id", cors(), function (req, res, next) { res.json({ msg: "example" }); });
Comments