CORS

DY·2022년 8월 10일
0

CS

목록 보기
8/10

  • SOP에러

배경

과거 수 년 동안, 한 사이트의 스크립트에서 다른 사이트에 있는 콘텐츠에 접근할 수 없다는 제약이 있었습니다.
같은 origin에서만 공유를 가능할수 있도록 SOP이 정해져 있었고. 정보의 확장을 위해 CORS를 허용하게 되었다.

SOP

  • Same-Origin Policy
  • 같은 출처의 리소스만 공유가 가능하다.
  • 여기서 말하는 출처는 scheme,hosts까지를 뜻함
  • 프로토콜, 호스트, 포트를 뜻하는데 하나라도 다르면 동일한 출처가 아니다.
  • 잠재적으로 해로울 수 있는 문서를 분리함으로써 공격받을 수 있는 경로를 줄여준다. 해킹 등 위협에서 보다 안전해질 수 있다.
    • 유저가 특정사이트에 로그인했을 때 다른 사이트에서 해당 로그인정보에 접근할 수 없는 것.
  • 다른 출처의 리소스 공유를 막는다.

CORS

  • Cross-Origin Resource Sharing

  • 다른출처의 리소스를 받아올 필요가 있을 때 접근 권한을 얻을 수 있게 됨.

  • 추가 HTTP 헤더가 필요하고, A 출처에서 실행중인 웹앱이 B 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제

  • 서버의 응답 헤더에 Access-Control-Allow_Origin을 작성하면 접근 권한을 얻을 수 있다.

  • Node.js 뿐만 아니라 Express, Fastify 등 다른 서버 환경에서도 CORS 설정을 할 수 있다.

CORS 동작방식



1. Preflight Request

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

  • 실제 요청을 보내기전 권한이 있는지 확인 함으로써 권한이 없을시 실제 리소스를 보내기전 권한이 없는 요청을 미리 거를 수 있어서 리소스 측면에서 유리하다.
  • CORS를 지원하지 않는 서버를 보호할수 있다. 이 서버는 SOP 요청이 오면 무조건 데이터를 전달하도록 설계되어있어서 보안에 취약하다.
  1. 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 값만 허용됩니다.
  1. Credentialed Request
  • 요청 헤더에 인증 정보를 담아 보내는 요청
  • 출처가 다를 경우 별도의 설정을 하지 않으면 쿠키를 보낼 수 없다.
  • 서버와 클라이언트 모두 CORS설정이 필요하다.
    • 프론트 측에서는 요청 헤더에 withCredentials : true 를 넣어줘야 합니다.
    • 서버 측에서는 응답 헤더에 Access-Control-Allow-Credentials : true 를 넣어줘야 합니다.
    • 서버 측에서 Access-Control-Allow-Origin 을 설정할 때, 모든 출처를 허용한다는 뜻의 와일드카드(*)로 설정하면 에러가 발생합니다. 인증 정보를 다루는 만큼 출처를 정확하게 설정해주어야 합니다.

CORS 설정방법

  1. Node.js 서버 - 응답헤더 설정
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");
})
  1. Express 서버
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" });
});
profile
화면에 보이는 모든것에 관심이 있습니다. 개발하면서 고민했던것들, 공부했던걸 기록하는 저장소입니다.

0개의 댓글