[TIL] [Web Server] 기초

전예훈·2023년 4월 4일
0

SOP CORS의 관계

SOP란?

SOP는 Same-Origin-Policy의 줌일말로 동일 출처 정책을 뜻한다.

한 마디로 정의 하면 같은 출처의 리소스만 공유가 가능하다.

여기서 출처는 다음과 같다.

SOP가 생겨난 이유?

SOP는 문서를 분리함으로써 공격받을 수 있는 경로를 줄여준다는 장점이 존재한다.

만약 네이버와 같은 웹페이지에 로그인해서 서비스를 이용하고 있다고 가정하고 서비스를 이용중이 아니더라도 로그아웃을 깜빡하여 브라우저에 로그인 정보가 남아 있을 수도 있다.

그 상태에서 다른사람이 악의를 가지고 내 정보와 권한으로 나 에게 피해를 입힐 수도 있기 때문에 SOP를 사용해 다른 사이트와의 리소스 공유를 제한해 내 로그인의 정보가 타 사이트로 새어나가는 것을 방지 할 수 있다는 장점이 존재한다.

한마디로 SOP는 다른 사이트와의 리소스 공유를 제한한다.


CORS란?

CORS (Cross-origin-Resource Sharing)의 줄임말로 교차 출처 리소스 공유를 뜻합니다.

CORS는 SOP 로인한 오류로 생기는 해결책이라고 볼 수 있는데

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

한마디로 정의하면 다른 출처의 리소스를 가져오려 했지만 SOP 때문에 접근때문에 막힌 것을 CORS설정을 통해 서버의 응답 헤더에서 접근 권한을 얻을 수 있다.

CORS 의 동작 방식

1. 단순 요청

Preflight의 요청없이 바로 서버로 요청을 날리게 된다.

GET, POST, HEAD 메서드가 들어있고 Content-Type이 들어있다.

2.프리플라이트 요청(Prefilght Request)

프리플라이트 요청은 왜 필요 할까?

  • 실제 요청을 보내기 전에 미리 권한 확인을 할 수 있기 때문에, 실제 요청을 처음부터 통째로 보내는 것보다 리소스 측면에서 효율적입니다.

  • CORS에 대비가 되어있지 않은 서버를 보호할 수 있습니다. CORS 이전에 만들어진 서버들은 SOP 요청만 들어오는 상황을 고려하고 만들어졌습니다. 따라서 다른 출처에서 들어오는 요청에 대한 대비가 되어있지 않았습니다.

3. 인증정보를 포함한 요청 (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 미들웨어를 사용해 보다 더 간단하게 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" });
});
profile
더욱더 QA스럽게!

0개의 댓글