웹은 기본적으로 '동일출저정책(Same Origin Policy, SOP)' 정책을 따른다.
이는 보안을 위한 기본정책으로, SOP는 하나의 출처(Origin)에서 로드된 문서나 스크립트가 다른 출처에 존재하는 리소스와 상호작용하지 못하도록 제약을 두는 것이다.
그런데, 간혹 이런 제약이 웹 응용프로그램을 만드는데 걸림돌이 되기도 한다.
Ajax 통신이 활발해 지고, 다른 사이트에 존재하는 Open API와 상호통신이 필요한 경우와 매쉬업(Mash-up)으로 새로운 2차 응용물을 개발하게 되면서.. 등등.. 이는 간혹 걸림돌이 된다.
근래 Node.JS로 서버를 만들고, Aptana Studio 자체 내장 웹서버로 몇 가지 테스트를 하고 있는데, 두 환경은 서로 다른 별도의 포트(Port)에서 웹을 동작시키기 때문에 여지없이 Cross Domain 문제가 발생한다.
호출하는 모든 웹 리소스를, Node.JS로부터 다운로드 받아서 실행하는 구조로 HTTP 서버를 구현하면 SOP 정책을 따를 수 있겠으나, 그렇지 못한 개발환경도 있을 터이고, 실제 서비스 환경에서는 더욱이 서로 다른 도메인(포트 포함)간 상호작용이 필요할 것이다.
SOP 정책을 우회하기 위해서는, 서버 측의 설정이 필요한데, 위 그림에서 친철히 안내하고 있는 것처럼 Access-Control-Allow-Origin 헤더, 즉 크로스 도메인으로 허용할 도메인 목록이 헤더로 제공되어야 한다.
이것을 CORS(Cross-Origin Resource Sharing)를 이용한 SOP 정책 우회라 한다.
Node.JS 환경에서 이 설정을 해보자.
다음과 같이, Node 기반 HTTP 서버의 응답헤더에 추가 해준다.
가장 중요한 설정은, Access-Control-Allow-Origin으로 허용할 도메인(포트)을 추가한다.
여러 도메인이 있을 경우, 중복해서 지정을 하거나 '*' 를 이용해 전체 허용도 가능하다.
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "http://127.0.0.1:8020");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
next();
});
app.get('/users', function(req, res) {
var tempUsers = [{id:'park', city:'pusan'}, {id:'kim', city:'seoul'}];
res.send(tempUsers);
});
app.listen(3002);
console.log("Listening on port 3002");
참고로 127.0.0.1:8020 도메인은, 필자의 Aptana Studio가 생성한 임의 주소이다.
이렇게 설정한 후, 클라이언트에서 요청하면 요청이 성공적으로 이뤄진다.
<script>
window.onload = function(){
var xhr = new XMLHttpRequest();
xhr.onload = function(){
console.log(xhr.response);
};
xhr.open("GET", "http://127.0.0.1:3002/users");
xhr.send();
};
</script>
그리고 언제나 그렇듯이 확장 라이브러리도 있다.
cors라는 이름의 Node.JS 확장인데, npm을 통해 설치하고 간단히 다음처럼 사용할 수 있다. 훨씬 간편하다.
var cors = require('cors')();
app.use(cors);
그래도 언제나 보안은 중요한 문제이니, SOP 정책에 존중하면서, 필요시 아주 제한적으로 적용하는 것을 권장함.
'모바일 > Javascript' 카테고리의 다른 글
[Node.js] Node With IIS (25) | 2016.07.19 |
---|---|
[AngularJS] 폼(form)과 유효성 검사 (8) | 2016.07.18 |
[AngularJS] REST API 통신(with Node.js) (10) | 2016.07.15 |
[Node.js] socket.io를 활용한 웹채팅 구현 (647) | 2016.07.15 |
[AngularJS] Route (12) | 2016.07.14 |