CORS

SuJin·2022년 10월 13일
0

SOP

Same-Origin Policy: 동일 출처 정책 = 같은 출처의 리소스만 공유 가능
프로토콜, 호스트, 포트 중 하나라도 다르면 동일한 출처X

  • https://www.~~~.com vs http://www.~~~.com
    프로토콜 다름. 동일 출처❌ ( https / http )
  • https://****.~~~.com vs https://~~~.com
    호스트 다름. 동일 출처❌ ( ****.~.com / ~.com )
  • http://~~~.com:81 vs http://~~~.com
    • http 프로토콜의 기본 포트는 80.
    • http://~~~.com = http://~~~.com:80
      포트 다름. 동일 출처❌ ( :81 / :80 )
  • https://~~~.com:443 vs https://~~~.com
    • https 프로토콜의 기본 포트는 443
    • https://~~~.com = https://~~~.com:443
      동일 출처

SOP는 잠재적으로 해로울 수 있는 문서를 분리함 → 공격받을 수 있는 경로 감소

  • 해킹 등의 위협으로부터 안전해 질 수 있다.
  • 다른 사이트와의 리소스 공유 제한

CORS

Cross-Origin Resource Sharing : 교차 출처 리소스 공유

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

브라우저는 SOP에 의해 기본적으로 다른 출처의 리소스 공유를 제한.

→ CORS를 사용하면 접근 권한 획득

CORS 동작 방식

1. 프리플라이트 요청 (Preflight Request)

실제 요청을 보내기 전, OPTIONS 메서드로 사전 요청을 보내 해당 출처 리소스에 접근 권한이 있는지 확인하는 것

브라우저는 서버에 실제 요청을 보내기 전에 Preflight 요청을 보내고, Response 헤더의 Access-Control-Allow-Origin 으로 요청을 보낸 출저가 돌아오면 실제 요청을 보낸다.

만약, Requset를 보낸 출처가 접근 권한이 없으면 브라우저에서 CORS에러를 띄우고, 실제 요청은 전달되지 않는다.

Preflihgt 요청이 필요한 이유

  • 실제 요청을 보내기 전에 미리 권한 확인을 할 수 있으므로, 실제 요청을 처음부터 통째로 보내는 것보다 리소스 측면에서 효율적
  • CORS에 대비가 되어있지 않은 서버 보호 가능
    • CORS 이전에 만들어진 서버들은 SOP 요청만 들어오는 상황을 고려하고 만들어짐

      → 다른 출처에서 들어오는 요청에 대한 대비 X

    • 응답을 보내기 전에 우선 요청 처리함

    • DELETE와 PUT과 같은 삭제, 수정 요청 방지 가능


2. 단순 요청 (Simple Request)

특정 조건이 만족되면 Preflight 요청을 생략하고 요청을 보내는 것

조건

  • 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 을 설정할 때, 모든 출처를 허용하는 와일드카드(*)로 설정하면 에러 발생. 출처 정확하게 설정해줘야 함

CORS 설정 방법

1. 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://~~~~.com");

// 인증 정보를 포함한 요청을 받을 경우
  response.setHeader("Access-Control-Allow-Credentials", "true");
})

2. Express 서버

CORS 미들웨어를 사용하여 보다 더 간단하게 CORS 설정 가능

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

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

//특정 도메인
const options = {
  origin: "https://~~~.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" });
});
profile
Anyone can be anything.

0개의 댓글