Cross-Origin Resource Sharing의 줄임말로, 교차-출처 리소스 공유라고 한다. 간단하게 말해 다른 출처라고 한다.
브라우저에서는 보안상의 이유로 다른 도메인에서 허용하지 않은 요청에 대하여 제한하고 있다. 일반적으로 다른 도메인 상에 대한 데이터 요청을 하게 될 경우 SOP에 의하여 제한 되게 된다.
서버 측에서 외부 요청에 대하여 완화적인 조치를 취하게 될 경우 다른 도메인에 대한 접근을 할 수 있게 된다.
SOP를 "동일 출처 정책"이라고 하는데, 말 그대로 동일 출처의 리소스만을 요청할 수 있다. 그렇기 때문에 다른 출처의 데이터 요청을 한다는 것은 정책에 위배되는 행위라고 한다.
동일한 출처는 프로토콜, 호스트, 포트가 동일할 경우에 대해서 같은 출처로 브라우저는 인식하게 된다.
출처란 Protocol, Hoist, 포트번호를 의미한다. 서버의 위치를 찾아가기 위해 필요한 가장 기본적인 것들을 합쳐둔 것이다.
보통 CORS 이슈가 발생한다면 서버 측에서 Access-Control-Allow-Origin 헤더에 접근권한을 설정할 수 있다. "*"를 설정하게 된다면 모든 외부 출처에서 접속할 수 있게 된다. 이 방법은 당장은 편리하여 좋아보이지만 보안적인 이슈에 직면할 수 있기 때문에 이러한 방법은 지양하는게 좋다.
그렇기에 외부에서 사용한다는 요청에 대한 심사를 거친 후 Access-Control-Allow-Origin에 외부 출처를 일일이 적용하는 것이 좋다.
하지만 서버측 헤더를 수정을 해야하기 때문에 서버측 헤더를 변경할 방법이 없다면 사용할 수 없는 방법이다.
Express 서버의 예
<script>
var app = require('express')()
var cors = require('cors')
// Access-Control-Allow-Origin 적용방법1: 직접 헤더에 적용
app.all('/*', function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Headers', 'X-Requested-With')
next()
})
// Access-Control-Allow-Origin 적용방법2: cors 미들웨어 사용
app.use(cors())
app.listen(80, function () {
console.log('http server is listening on port 80')
})
</script>
다른 도메인에 접근할 수 있는 우회적인 기법 중에 JSONP( JSON with Padding )방법이 있다.
웹 브라우저에서 실행되는 JavaScript는 통신을 이용해 외부 출처에서 데이터를 받아오는 것이 불가능하지만, HTML <script>
요소는 외부 출처로 부터 조회된 내용을 실행하는 것이 허용되고 있다. 다만 JavaScript 문법 오류가 발생하게 된다.
문법 오류가 발생하는 이유는 JavaScript에서 변수, 상수로 정의 되지 않고 json형식이 입력되면서 발생하게 된다.
JSONP는 이러한 웹브라우저 특성을 이용하여 json 데이터를 서버가 콜백함수로 감싸 JavaScript 문법을 유효하게 만들어 전달하여 클라이언트에서 응답을 받을 수 있게 된다.
<script type="application/javascript"
src=http://server.example.com/Users/1234?callback=parseResponse">
</script>
praseResponse({"Name": "Foo", "Id": 1234, "Rank": 7})
JSONP 내용을 확인해보시면 아시겠지만 결국 서버에서 패딩을 요청한 콜백함수로 감싸줘 전송을 해야한다는 문제가 발생한다. 외부 API에서 콜백함수를 제공하지 않는다면 사용할 수 없는 방법이 된다.
외부 도메인서버에 접근하고자할 때 바로 외부 도메인 서버를 통하는 것이 아닌 자신의 서버를 매개로 하여 외부서버에 요청하는 방식이다.
서버에서 요청을 하게될 때에는 브라우저 규약인 CORS 정책에 영향을 받지 않는다.
그러한 이점을 이용하여 Proxy Server라는 출처를 통하기 때문에 CORS 정책을 위반하지 않게되어 우회 할 수 있게된다.
Express 서버일 경우 express-http-proxy 미들웨어를 통해서 Proxy Server 구현이 가능하다.
const { createProxyMiddleware } = require("http-proxy-middleware");
module.exports = function (app) {
app.use(
"/api",
createProxyMiddleware({
target: "http://localhost:8080",
changeOrigin: true,
})
);
};