SOP(동일 출처 정책)
Same-Origin Policy의 약자로,
같은 출처의 리소스만 가져올 수 있어
동일 출처가 아니라면 브라우저가 막아버리는 것을 말한다.
동일 출처?
//https:unong_story:014
프로토콜, 도메인, 포트{80, 443 등 (기본 포트는 생략될 수 있음)}가 모두 같은 것
예시) 동일 출처
1.
URL 1: https://www.example.com/page1.html
URL 2: https://www.example.com/page2.html
URL 모두 https:// 프로토콜, www.example.com 도메인, 그리고 기본 포트 443(HTTPS)이 일치
2.
URL 1: http://www.example.com/index.html
URL 2: http://www.example.com/about.html
URL 모두 http:// 프로토콜, www.example.com 도메인, 기본 포트 80(HTTP)이 일치
한계
현대엔 시대의 흐름에 따라 웹 기술로 할 수 있는 것들이 많아졌고,
자연스럽게 다른 출처로 요청을 하고 응답을 받아오는 수요가 증가했다.
=> 다양한 출처에서 데이터를 안전하게 공유할 수 있도록 하는 방법이 필요
=> CORS 등장
CORS
Cross-Origin Resource Sharing의 약자로,
웹 브라우저는 보안상의 이유로 다른 출처에서의 리소스 접근을 제한,
이를 해제하고 특정 조건에서만 접근을 허용하기 위해 사용한다.
쉽게 설명하기 위해 react로 todo 공부를 하다 나온 콘솔 창을 가져와봤다.
// Cors로 막힌 콘솔 에러
Access to fetch at 'http://localhost:4000/api/todo'
from origin 'http://localhost:5173' has been blocked by CORS policy
: No 'Access-Control-Allow-Origin' header is present on the requested resource.
If an opaque response serves your needs,
set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Client : localhost:3000 (react 개발서버)
Server : localhost:4000
=> Client와 Server의 Origin(출처=포트 3000이랑 4000)이 다르다.
Client에서 Server의 데이터를 막 가져간다?
ex1.com에서 ex2.com의 데이터를 막 꺼내가려 한다
=> 안됨! Origion이 다르면 무조건 막는다.
이제 다른 출처에서 접근할 수 있게 허용하기 위해 CORS를 설정을 해보겠다.
CORS 설정 방법
서버에서 설정된 HTTP 헤더 작성
Access-Control-Allow-Origin
리소스에 접근할 수 있는 주소
=> 어떤 도메인(Origin)에서의 요청을 허용할지를 지정
*를 사용하면 모든 도메인에서 요청을 허용
Access-Control-Allow-Methods
클라이언트 → 서버로 요청할 때 사용할 HTTP 메소드
ex ) GET, POST, PUT, DELETE, OPTIONS 등...
Access-Control-Allow-Headers
클라이언트 → 서버로 요청할 때 사용할 HTTP 헤더
ex ) Content-Type, Authorization 등...
예시 ) GPT Express.js (Node.js)
const express = require('express');
const app = express();
// 모든 도메인에서의 요청을 허용
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*'); // 특정 도메인을 허용하려면 '*' 대신 도메인명을 입력
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
next();
});
app.get('/', (req, res) => {
res.send('CORS 설정 완료');
});
app.listen(3000, () => {
console.log('서버가 3000번 포트에서 실행 중입니다.');
});