키워드 : SOP, CORS, Web Server
SOP(Same-Origin Policy) : 동일 출처 정책
- 같은 출처의 리소스만 공유가 가능한 정책.
- 출처 = 프로토콜 + 호스트 + 포트 (이 중 하나라도 다르면 동일 출처로 보지 않는다)
- 단, 프로토콜의 기본 포트는 생략 가능
ex) https://codestates.com:443 === https://codestates.com
- 단, 프로토콜의 기본 포트는 생략 가능
- SOP를 사용하는 이유 : 다른 사이트와 리소스 공유를 제한함으로써 개인 정보 등이 타 사이트의 코드에 의해 유출되는 것을 방지.
- 기본적으로 모든 브라우저에서 SOP를 채택.
- 다른 출처의 리소스를 받아와야하는 경우에는 CORS를 사용.
CORS(Cross-Origin Resource Sharing) : 교차 출처 리소스 공유
교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제이다.
(출처 : MDN)
- CORS 설정을 통해 요청에 대한 응답 헤더에 "Acces-Control-Allow-Origin"을 작성하면 클라이언트 서버는 접근 권한을 얻게 된다.
CORS 동작 방식
1. 프리플라이트 요청(Preflight Request)
- 실제 요청에 앞서, 사전 요청을 보냄으로써 해당 출처 리소스에 접근 권한이 있는지 확인하는 것.
- OPTIONS 메서드를 사용.
- 접근 권한이 없을 경우 브라우저에서 CORS 에러를 띄우고, 실제 요청은 전달되지 않는다.
2. 단순 요청(Simple Request)
- 특정 조건 충족 시, 프리플라이트 요청 생략 후 바로 실제 요청을 진행.
- 조건 :
- GET, HEAD, POST 요청 중 하나여야 함.
- 자동으로 설정되는 헤더 외에, Accept, Accept-Language, Content-Language, Content-Type 헤더의 값만 수동으로 설정할 수 있다.
3. 인증 정보를 포함한 요청(Credentialed Request)
- 요청 헤더에 인증 정보를 담아 보내는 요청
- 프론트, 서버 양측 모두 CORS 설정이 필요
예시 코드
const http = require("http");
const PORT = 4999;
const ip = "localhost";
const server = http.createServer((request, response) => {
// const { method, url } = request로 해줄 경우, 아래에서 request.method 대신 method로만 코드 작성 가능.
if (request.method === "OPTIONS") {
response.writeHead(200, defaultCorsHeader);
response.end("hello mini-server sprints");
}
if (request.method === "POST" && request.url === "/upper") {
let body = [];
request
.on("data", (chunk) => {
body.push(chunk);
})
.on("end", () => {
body = Buffer.concat(body).toString();
response.writeHead(201, defaultCorsHeader);
response.end(body.toUpperCase());
});
} else if (request.method === "POST" && request.url === "/lower") {
let body = [];
request
.on("data", (chunk) => {
body.push(chunk);
})
.on("end", () => {
// 여기서 `body`에 전체 요청 바디가 문자열로 담겨있습니다.
body = Buffer.concat(body).toString();
response.writeHead(201, defaultCorsHeader);
response.end(body.toLowerCase());
});
} else {
request.on("error", (err) => {
response.statusCode = 400;
response.end();
});
}
console.log(
`http request method is ${request.method}, url is ${request.url}`
);
});
server.listen(PORT, ip, () => {
console.log(`http server listen on ${ip}:${PORT}`);
});
const defaultCorsHeader = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Accept",
"Access-Control-Max-Age": 10,
};
Reference
https://nodejs.org/ko/docs/guides/anatomy-of-an-http-transaction/
HTTP 트랜잭션 해부 | Node.js
Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.
nodejs.org
느낀점
개념 학습도 하고, 과제도 풀어보면서 대강 감은 익혔는데 아직 완벽하게 개념 정리가 모두 되지 않은 것 같다. 아무래도 계속 보면서 익숙해져야 할 듯 하다.
'코딩' 카테고리의 다른 글
모의 기술 면접 질문 리스트 (0) | 2022.06.21 |
---|---|
[Web server] 기초 2 / Refactor Express (0) | 2022.06.17 |
[React] 클라이언트 Ajax 요청 (0) | 2022.06.14 |
[HTTP] Web application architecture (0) | 2022.06.12 |
[HTTP] REST API (0) | 2022.06.10 |