본문 바로가기

프론트엔드 블로깅 챌린지/FE

SEB_FE_ 블로깅 챌린지 _ 36일차 ( web server - cors 리뷰 )

< SOP >  - Same - Origin - Policy : 동일 출처 정책 

 

 1. 기본 개념 : 같은 출처 즉, 프로토콜, 호스트, 포트가 같아야 리소스 공유가 가능하다. 

출처의 개념.

 

-> http의 기본 포트는 80 , https프로토콜의 기본 포트는 443.

-> 문서를 분리함으로써 해킹 등 공격 받을 수 있는 경로를 줄여줌.

-> 클라이언트와 서버도 다른 출처를 가지므로 앞으로 다른 출처의 리소스를 받아오는 방법을 배울 것임. ( CORS )

 

 

 

 

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

 

1. 기본 개념 : 추가 HTTP 헤더를 사용하여, 다른 출처의 자원에 접근할 수 있는 권한을 부여함.

                        : SOP에 막힌 다른 출처의 리소스 공유를  CORS를 사용해 접근 권한을 얻을 수 있음.

 

 

 

2. CORS 동작 방식 

-> 프리플라이트 요청 ( Preflight Request )

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

       다른 출처에서  들어오는 요청을 수행하지 않고 , 해당 권한을 확인하기 위해 사용.

 

    : 성공 시 응답 헤더에서 Access-Control-Allow-Origin가 돌아오면 실제 요청을 진행.

      실패 시 브라우저에서 CORS 에러를 띄우고, 실제 요청은 전달되지 않음.! 

 

 

 

-> 단순요청 ( 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-Origin을 설정할 때, 와일트 카드(* : 모든 출처 허용) 설정 금지.

 

 

 

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