Web Server 기초

KoEunseo·2022년 8월 11일
0

CS

목록 보기
3/8

SOP :: Same Origin Policy

같은(same) 출처(origin)의 리소스만 공유 가능하다.

Origin

Origin = { https://, www.codestates.com, :443 }/course
출처 = { 프로토콜, 호스트, 포트} 의 조합으로 이루어져있다.

해로울 수 있는 문서를 분리함으로써 공격받을 수 있는 경로를 줄여준다.

CORS :: Cross-Origin Resource Sharing

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

CORS 동작 방식

1. PreFlight Request

찐요청을 보내기 전에 Options 메서드로 사전 요청을 보내서
해당 출처 리소스에 접근 권한이 있는지를 먼저 확인한다.
이때 보내는 사전요청을 프리플라이트 요청이라고 한다.
Access-Control-Allow-Origin으로 요청을 보낸 출처가 돌아와야한다.
확인이 된 후에 찐요청을 보낸다.

만일 접근 권한이 없다면 Access-Control-Allow-Origin 응답 헤더에 출처가 돌아오지 않는다.

왜 프리플라이트를 쓸까??

요청을 처음부터 통째로 보내는 것보다 리소스 측면에서 효율적이다.
그리고 CORS에 대비하지 않은 서버를 보호할 수 있다.
실행되어서는 안되는 Cross Origin 요청이 실행되는 것을 방지할 수 있다.

Simple Request

특정 조건이 만족되면 플리플라이트 요청을 생략하고 요청을 보낸다.

Simple Request 조건

  • GET, HEAD, POST 요청 중 하나여야 한다.
  • 자동으로 설정되는 헤더 외에,
    { Accept, Accept-Language, Content-Language, Content-Type }
    헤더의 값만 수동으로 설정할 수 있다.
    • Content-Type 헤더에는
      { application/x-www-form-urlencoded, multipart/form-data, text/plain }
      값만 허용한다.

Credentialed Request(인증정보 포함한 요청)

요청 헤더에 인증 정보를 담아 요청을 보낸다. 출처가 다를 경우에는 별도의 설정을 하지 않으면 쿠키를 보낼 수 없다. 이 경우에는 프론트, 서버 양측 모두 CORS 설정이 필요하다.

  • 프론트 측 요청 헤더
    withCredentials : true 가 있어야 함
  • 서버 측 응답 헤더
    Access-Control-Allow-Credentials : true 가 있어야 함
    서버 측에서 Access-Control-Allow-Origin 을 설정할 때, 모든 출처를 허용한다는 뜻의 와일드카드(*)로 설정하면 에러가 뜸. 출처를 정확하게 설정한다.

CORS 설정 방법

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");
})

Express 서버

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" });
});

0개의 댓글