본문 바로가기

3.구현/HTML5&Javascript

[javascript] JSONP 란?

들어가기

JSONP(JSON with Padding)는 크로스 도메인(cross domain)으로 인한 접근 제한 문제를 회피하기 위한 방법이다. 크로스-도메인 정책으로 다른 서버에 Ajax를 요청할 수 없다. JSONP을 간단히 설명하면 클로스-도메인을 우회하여 요청하는 방법으로 ajax를 사용하지 않고 script 태그를 사용한 요청방법이다. 하나씩 살펴보자.

작성자: ospace114@empal.com, http://ospace.tistory.com/

크로스 도메인이란?

공격자가 가장 흔하게 사용하는 해킹 기법이 XSS(Cross-Site Scripting)이 있다. 온라인 게시판에 입력 받스가 있다면 내용에 자바스크립트를 입력할 수 있다. 또는 링크를 만드는 곳에 자바스크립트 실행하도록 만들 수도 있다. 또는 버튼 같은 이벤트가 발생하는 곳에서도 자바스크립트를 실행할 수 있다. 이렇게 실행되는 자바 스크립트로 사용자가 입력되는 데이터를 확인할 수 있을 뿐만 아니라 서버측에서 받아오는 데이터를 확인할 수 있다. 그래서 정상적인 사용자가 자기도 모르게 공격 코드를 실행하거나, 자신의 정보를 다른 곳에 전달할 수 있다.

이를 방지하기 위해 입력되는 모든 문자열 확인(XSS 필터링)하거나 서버 측에 넘오는 데이터에 대해 확인한다.

다른 방지 방법으로 웹브라우저에서는 기본적으로 동일 출처 정책이 있다. 동일 출처 정책은 출처가 다른 리소스를 가져오는데 제한을 가하는 메커니즘이다. 이렇게 제한하는 이유는 다른 악의적인 사이트에 접근하거나 공격자에게 중요 데이터를 전달하지 못하도록 막기위한 목적이다. 보통 삽입된 이미지나 스크립트인 경우는 이런 동일 출처 제약에서 예외된다. 이외에도 비디오나 CSS도 포함된다.

일반적인 Ajax 요청 처리

일반적인 Ajax 요청은 다음 처럼 실행이 가능하다.

fetch('http://192.168.1.2:8080/user/1')
    .then(res => res.json())
    .then(json => {
       // json data
    });

응답이 JSON 형태인 경우 변환해서 처리할 수 있다. 서버측 응답은 JSON 혹은 XML 등의 단순 데이터 형태로 반환된다. 예를 들어 JSON 형태 응답이면 다음 처럼 응답될 것이다.

{"id": 1, "name":"foo"}

만약 서버가 크로스 도메인을 허용하지 않을 경우 크롬인 경우 에러가 발생하면서 응답을 얻을 수 없다. 크롬이라면 콘솔 창에 아래와 같은 메시지가 보인다.

  • No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

과거에서는 웹페이지 제공하는 서버와 Ajax을 호출하는 서버가 같은 도메인이라서 문제가 없지만, 현재는 프론트엔드 서버와 백엔드 서버가 분리된 경우가 많아서 도메인이 달라질 경우도 많다. 또는 다른 서버에 데이터를 요청하거나 제공할 경우도 많이 생긴다. 이런 환경으로 인해 제약사항이 있는 환경에서 서버에서 데이터를 가져와야할 경우가 생긴다. 이때 JSONP를 활용할 수 있다.

JSONP 요청처리

JSONP가 어떻게 요청 처리하는지 알아보자. JSONP에서는 Ajax와 요청 방식이 다르다. 서버로 요청하는 경우 script 태그를 생성하고 src에 호출할 대상 URL을 지정하고 추가한다.

브라우저측에서 실행과정을 보면 script 태그를 생성하고 추가하게 되면 추가된 태그가 실행된다. 그러면 src에 지정된 자바스크립트파일 다운받고 실행하게 된다.

var obj = document.createElement('script');
obj.src = 'http://192.168.1.2:8080/user/jsonp/1';
document.body.append(obj);

서버측 응답은 Javascript 파일 내용을 생성하고 반환되며 브라우저에서 실행된다.

myFunc({"name":"foo", "id":1})

브라우저에 myFunc()가 있다면 해당 함수가 실행되면서 서버 응답 데이터를 처리할 수 있다. 위의 자바스크립트리를 정리하면 아래와 같은 형태가 된다.

function myFunc(data) {
  // data 처리
}

var obj = document.createElement('script');
obj.src = 'http://192.168.1.2:8080/user/jsonp/1';
document.body.append(obj);

myFunc()가 정의되고 요청 URL에 의해 리턴된 자바스크립트가 실행되면서 myFunc()가 호출되고 인자에 서버에서 리턴된 데이터가 담겨져서 넘겨진다.

마무리

위의 방식은 간단하게 JSONP을 사용하는 방법이다. 생각보다 JSONP는 어렵지 않다. 원칙적으로 JSONP 구조가 권장하는 방식은 아니어서 너무 남발하는 것은 좋지 않다. 그러나 사용하는 관점에서는 여러 방식으로 응용할 수 있다.

부족한 글이지만 여러분에게 도움이 되기를 바랍니다. 모두 즐거운 코딩 생활되세요. ^^ ospace.

참고

[1] JSONP, https://www.w3schools.com/js/js_json_jsonp.asp

[2] 동일 출처 정책, https://developer.mozilla.org/ko/docs/Web/Security/Same-origin_policy

반응형