그저 내가 되었고

항해99) 6주차:: 미니 프로젝트; 📚CORS 본문

개발/항해99 9기

항해99) 6주차:: 미니 프로젝트; 📚CORS

hyuunii 2022. 10. 23. 22:55

CORS(Cross-Origin Resource Sharing)

추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제. 웹 애플리케이션은 리소스가 자신의 출처(도메인, 프로토콜, 포트)와 다를 때 교차 출처 HTTP 요청을 실행.

 

'출처'란?

https://beomy.github.io/tech/browser/cors/

서버의 위치를 의미하는 https://google.com과 같은 URL들은 마치 하나의 문자열 같아 보여도, 사실은 여러 개의 구성 요소로 이루어져있다. 이때 출처는 Protocol Host, 그리고 위 그림에는 나와있지 않지만 :80, :443과 같은 포트 번호까지 모두 합친 것을 의미한다. 즉, 서버의 위치를 찾아가기 위해 필요한 가장 기본적인 것들을 합쳐놓은 것이다. Protocol + Host + Port 3가지가 같으면 동일 출처(Origin)라고 한다.

 


'CORS'란?

왼쪽의 핸드폰의 URL은 domain-a.com,

오른쪽 서버의 URL은 domain-a.com과 domain-b.com 2가지.


domain-a.com 유저가 domain-a.com 서버에 요청하면 동일 정책이기 때문에 아무런 문제가 없지만,
domain-a.com 유저가 domain-b.com 서버에 요청하면 호스트(Host_가 다르기 때문에 다른 출처 요청을 함.

 

도메인 이외에, 같은 프로젝트 내에 정의된 css 파일 요청은 동일 출처 요청이고,

font같은 경우에는 다른 외부 사이트에서 실시간으로 import를 통해 가져온다면 다른 출처 요청.

이처럼, 같은 출처가 아닌 외부에 자원을 요청하는 경우가 있는지 잘 확인해보아야 함.

 

기본적으로 동일 출처 요청만 자유롭게 요청이 가능하며 동일 출처 정책(Same-Origin Policy),

하지만 기준을 완화하여 다른 출처 요청도 할 수 있도록 기준을 만든 체제가 다른 출처 정책(Cross-Origin Policy).


CORS 이슈 해결법?

1. Simple Request인 경우

  • HTTP Method가 GET, POST, HEAD 중 하나이거나 
  • Content-Type이 text/plain, application/x-www-form-urlencoded, multipart/form-data 중 하나일때

어떤 특정 요청에만 적용 하고 싶다면 cross-origin을 허락하는 헤더를 추가해 문제를 해결 가능.

app.get('/', function(req, res) {
    res.header("Access-Control-Allow-Origin", "*");
    .....
})

 

2. 미들웨어 cors 사용

명령어 : npm install cors(추가하면 package.json에 cors가 들어옴)

모듈 불러오기: app.js에 코드 추가👇🏻

//cors 모듈을 불러옵니다.
const cors = require('cors');

//cors설정
app.use(cors());

 

cors 옵션을 사용할 경우👇🏻

var safesitelist = ['https://domain-a.com', 'http://domain-a.co.kr']

var corsOptions = {
    origin: function(origin, callback) {
        var issafesitelisted = safesitelist.indexOf(origin) !== -1;
        callback(null, issafesitelisted);
    },
    credentials: true
}

//cors에 옵션사용할경우
app.use(cors(corsOptions));

 

app.js 전체 소스👇🏻

// node_modules의 express 패키지를 가져온다.
var express = require('express')

//cors 모듈을 불러옵니다.
var cors = require('cors');

//app이라는 변수에 express 함수의 변환 값을 저장한다.
var app = express()

var safesitelist = ['https://domain-a.com', 'http://domain-a.co.kr']

var corsOptions = {
    origin: function(origin, callback) {
        var issafesitelisted = safesitelist.indexOf(origin) !== -1;
        callback(null, issafesitelisted);
    },
    credentials: true
}

//cors설정
app.use(cors());

//cors에 옵션사용할경우
//app.use(cors(corsOptions));

//환경변수에서 port를 가져온다. 환경변수가 없을시 5050포트를 지정한다.
var port = app.listen(process.env.PORT || 5050);

//REST API의 한가지 종류인 GET 리퀘스트를 정의하는 부분입니다.
//app.get이라고 작성했기 때문에 get 요청으로 정의가 되고
//app.post로 작성할 경우 post 요청으로 정의가 됩니다.
//REST API의 종류 (get, post, update, delete 등등)을 사용하여 End Point를 작성하실 수 있습니다.
app.get('/', function(req, res) {
    res.send("<h1>Express server Start</h1>")
})

// express 서버를 실행할 때 필요한 포트 정의 및 실행 시 callback 함수를 받습니다
app.listen(port, function() {
    console.log('start! express server');
})