개발을 배우다가 한번쯤은 접할 수도 있는 단어 CORS. 이번에 알아보면서 개인적으로 상당히 어려움을 느꼈다.(사실 자주) CORS(Cross-Origin Resource Sharing)는 우리말로는 교차 출처 리소스 공유라고 한다. 더 난해지는 느낌인데 CORS를 설명하기 이전에 나온 배경이나, 다른 개념부터 알아보는 것이 좋을거 같다.
웹 생태계가 발전에 따라 한 API에서 다른 사이트의 리소스를 가져오는 경우가 많아지고 있었다고 한다. 이 과정에 Client 브라우저에 저장된 정보들(Cookie라든지... 로그인 정보와 같은..?) 사용 하는 것을 방지하기 위해 나온 것이라고 한다. 브라우저의에 저장된 정보가 생각보다 허술하다는 것이다.
SOP는 영어 뜻 그대로 동일한 출처에서만 리소스를 공유 할 수 있도록 규칙을 만든 것이라고 한다.
하지만 웹 소스를 안가져오는 것이 말이 안되기 때문에 예외 조항을 두었는데 그 예외 조항 중 하나가 CORS 정책을 지킨 리소스 요청이라고 한다.
크롬브라우저에서 나오는 CORS경고는 사실 CORS 정책을 지키라는 새빨간 조언일 뿐이었다는 것이었다.
그렇다면 Origin 출처는 무엇일까.
SOP에서 판단하는 Origin은 URL 주소 기준으로 잡는다고 한다. Scheme
, Host
, Ports
로 나눠 3가지 조건이 충족되면 Origin으로 판단된다고 한다. 예를 들면 http:// eotkds.com
은 http:// 는 Scheme
, eotkds.com 은 Host
로 판단하고, eotkds.com 뒤에 숨겨져 있는 Port
까지 판단한다고 한다. http:// 의 기본 Port는 :80 이고, 이 경우 Port
는 :80인 셈이다.
Origin 주소 기준을 잡고 3가지가 충족 되지않은 리소스에 대해서는 브라우저가 리소스를 버리게 된다고한다. 여기서 중요한 것은 브라우저라는 것이다. 그렇기 때문에 서버 끼리는 잘 되다가도 프론트를 통할 때 갑자기 막히는 현상이 일어난다는 것이다.
CORS 동작 방식으로 다음과 같다
프리플라이트 요청(Preflight Request)
Simple Request
Credential Request
참조 사이트에는 이렇게 3가지 방법을 소개 하는데, 여기서는 우선 Preflight Request 와 Npm 사이트에서 Cors 라이브러리 참고해 설명하도록 하겠다. 추후에 부족한것은 추가 포스팅 하려고 한다.(추가 포스팅은 무적의 단어가 되어가는 것 같다😂)
Preflight 방식 이미지출처:https://evan-moon.github.io/2020/05/21/about-cors/위 3가지 CORS 방식은 시나리오 별로 이해 할 수 있다고 한다. preflight방식은 가장 많이 마주치는 시나리오로 이해 할 수도 있다고 한다. 그림을 보면 이해가 조금 잘 될 것이다. fetch
요청을 받은 브라우저는 요청을 보내기전 예비 요청(Preflight)
를 보내고 서버는 이 예비 요청에 대한 응답으로 어떤것을 허용하고 어떤것을 허용하지 않는지에 대한 정보를 넘겨준다고 한다. 이후 브라우저는 자신이 보낸 요청값과 서버가 응답에 담아준 허용정책을 비교한 후, 요청을 보내도 안전하다고 판단되면 엔드포인트로 요청을 날리는 것이라고 한다.
npm에서 cors 패키지는 node.js 기반을 둔 것이고, npm 사이트 예로는 express 사용을 예시로 들어서 참고 하여 설명하겠다.
// Simple Usage
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors()) // 모든 도메인을 허용
//Sing Route
var express = require('express')
var cors = require('cors')
var app = express()
app.get('/products/:id', cors(), function (req, res, next) {
res.json({msg: 'This is CORS-enabled for a Single Route'})
})
app.listen(80, function () {
console.log('CORS-enabled web server listening on port 80')
})
//Configuring CORS
var express = require('express')
var cors = require('cors')
var app = express()
var corsOptions = {
origin: 'http://example.com',
optionsSuccessStatus: 200
}// some legacy brower(익스플로러같은 것)들은 204
CORS 패키지만 설치해봐서 안다고 블로깅하려다가 정말 뚜들겨 맞은 기분이다. 다시 준비가 필요한듯 하다.
[웹개발 짜증유발자! CORS가 뭔가요?, YouTube, 2022년05월03일 접속]
https://www.youtube.com/watch?v=bW31xiNB8Nc
[CORS는 왜 이렇게 우리를 힘들게 하는걸까?, GitHUb, 2022년05월03일 접속]
https://evan-moon.github.io/2020/05/21/about-cors/
[[Web] CORS 동작 방식과 해결 방법, INGG, 2022년05월03일 접속]
https://ingg.dev/cors/
[SOP(Same-Origin Policy), velog, 2022년05월03일 접속]
https://velog.io/@ppou/SOP
[NPM:cors, npm, 2022년05월03일 접속]
https://www.npmjs.com/package/cors