JSON-P
1. 개요
1. 개요
JSON-P는 JSON with Padding의 약자이다. 이는 웹 브라우저의 보안 정책인 동일-출처 정책을 우회하여, 다른 도메인에 위치한 서버로부터 데이터를 요청할 수 있게 해주는 방법이다. 2005년 Bob Ippolito에 의해 제안되었다.
이 기술은 HTML의 <script> 요소가 출처에 관계없이 외부 자바스크립트 파일을 실행할 수 있다는 점을 활용한다. 서버는 일반 JSON 데이터를 클라이언트가 미리 지정한 콜백 함수 호출로 감싸서 전송하며, 브라우저는 이를 스크립트로 받아들여 실행함으로써 데이터를 획득한다.
주로 웹 개발에서 교차 도메인 API 호출을 구현하는 데 사용되었으나, 보안상의 취약점을 내포하고 있다. 이러한 문제로 인해 현대 웹 표준에서는 CORS(Cross-Origin Resource Sharing)가 JSON-P를 대체하는 기술로 권장된다.
2. 동작 원리
2. 동작 원리
JSONP의 동작 원리는 웹 브라우저의 동일 출처 정책이라는 보안 제약을 우회하는 데 있다. 이 정책은 기본적으로 자바스크립트 코드가 자신이 로드된 도메인과 다른 서버로부터 데이터를 직접 요청하는 것을 차단한다. 그러나 HTML의 <script> 태그는 이 정책의 예외로, 외부 출처에서 자바스크립트 코드를 가져와 실행하는 것이 허용된다. JSONP는 이 특성을 교묘하게 이용한다.
클라이언트는 데이터를 요청할 때, 서버가 반환할 데이터를 처리할 콜백 함수의 이름을 매개변수(예: callback=myFunction)로 함께 전달한다. 서버는 일반적인 JSON 데이터를 받으면, 이 데이터를 클라이언트가 지정한 콜백 함수 호출문으로 감싼다. 예를 들어 {"name":"Foo"}라는 데이터가 myFunction이라는 콜백으로 요청되었다면, 서버는 myFunction({"name":"Foo"})와 같은 형태로 응답한다.
이 응답은 순수한 JSON이 아닌, 실행 가능한 자바스크립트 프로그램이 된다. 브라우저는 <script> 태그를 통해 이 코드를 로드하고 즉시 실행하며, 이 과정에서 미리 정의된 콜백 함수가 호출되어 데이터를 인자로 받아 처리할 수 있게 된다. 이 방식은 XMLHttpRequest나 Fetch API를 사용하지 않고도 교차 도메인 요청을 가능하게 했다.
그러나 이 방식은 본질적으로 서버에서 반환된 임의의 자바스크립트 코드를 무조건 실행하게 되므로, 악의적인 코드 주입에 취약한 심각한 보안 문제를 내포한다. 또한 요청 방식을 GET 메서드로만 제한한다는 한계도 있다. 이러한 문제들로 인해 JSONP는 이후 등장한 CORS라는 표준화된 안전한 메커니즘에 의해 대체되는 추세이다.
3. 구문 예시
3. 구문 예시
JSON-P 요청의 핵심은 서버가 반환하는 데이터를 클라이언트가 미리 정의한 자바스크립트 함수 호출로 감싸는 것이다. 클라이언트는 요청 시 callback이라는 쿼리 문자열 매개변수를 통해 함수명을 지정한다. 예를 들어, 클라이언트가 handleData라는 함수를 콜백으로 사용하려면, 다음과 같이 스크립트 태그의 src 속성에 요청을 추가한다.
서버는 평범한 JSON 객체 대신, 이 객체를 인자로 하는 함수 호출문을 반환한다. 클라이언트가 http://api.example.com/user?id=123&callback=handleData로 요청을 보내면, 서버는 {"name": "홍길동", "id": 123}이라는 데이터를 handleData({"name": "홍길동", "id": 123}); 형태로 응답한다. 웹 브라우저는 이 응답을 스크립트로 받아들여 즉시 실행하며, 이때 미리 정의된 handleData 함수가 호출되어 데이터를 처리할 수 있게 된다.
콜백 함수명은 일반적으로 callback 파라미터로 전달되지만, jsonp나 cb 등 서버 API에 따라 다른 이름을 사용하기도 한다. 클라이언트 측 코드에서는 요청을 보내기 전에 전역 스코프에 해당 콜백 함수를 반드시 정의해야 한다. 아래는 jQuery 라이브러리를 사용한 구문 예시이다. jQuery는 내부적으로 콜백 함수를 자동 생성하고 관리하여 편리하게 JSON-P 요청을 처리할 수 있게 한다.
```javascript
$.ajax({
url: 'http://api.example.com/data',
dataType: 'jsonp',
jsonpCallback: 'myCallback',
success: function(data) {
console.log(data);
}
});
```
이 방식은 동일 출처 정책을 우회할 수 있지만, 서버가 악의적인 스크립트를 반환할 경우 이를 제어할 수 없다는 본질적인 보안 문제를 안고 있다. 또한 에러 핸들링이 제한적이고, HTTP 메서드가 GET 방식으로만 고정되는 한계가 있어, 현대 웹 개발에서는 CORS를 표준으로 채택하는 추세이다.
4. 보안 문제
4. 보안 문제
JSONP는 교차 도메인 데이터 요청을 가능하게 하지만, 본질적인 보안 취약점을 내포한다. 가장 큰 문제는 서버 응답을 검증하지 않고 자바스크립트 코드로 실행한다는 점이다. 악의적인 서버가 콜백 함수에 악성 코드를 담아 응답하면, 클라이언트는 이를 신뢰하고 실행하게 되어 크로스 사이트 스크립팅(XSS) 공격에 노출된다. 또한, 요청을 보낸 서버가 해킹당하거나 악의적으로 변조될 경우, 정상적인 클라이언트도 악성 스크립트를 실행하는 경로가 될 수 있다.
이러한 위험은 JSONP의 동작 방식에서 기인한다. 동일-출처 정책을 우회하기 위해 <script> 태그를 사용하므로, XMLHttpRequest를 통한 통신과 달리 HTTP 상태 코드를 확인하거나 헤더를 검증하는 표준 메커니즘이 작동하지 않는다. 결과적으로 클라이언트는 응답의 출처와 무결성을 신뢰할 수 있는 방법이 없다.
이러한 보안 문제로 인해 JSONP는 현대 웹 개발에서 권장되지 않으며, 더 안전한 대체 기술인 CORS(Cross-Origin Resource Sharing)로 빠르게 대체되고 있다. CORS는 브라우저와 서버가 협력하여 안전한 교차 출처 요청을 정의할 수 있는 표준 프로토콜을 제공한다.
5. 대체 기술 (CORS)
5. 대체 기술 (CORS)
JSONP의 주요 대체 기술은 교차 출처 리소스 공유(CORS)이다. CORS는 W3C에서 권고하는 표준 웹 기술로, 웹 브라우저와 서버가 안전하게 교차 출처 요청을 주고받을 수 있도록 하는 메커니즘을 제공한다. JSONP가 동일 출처 정책을 우회하기 위해 스크립트 태그를 악용하는 해킹(Hack)에 가까운 방식이라면, CORS는 브라우저와 서버 간의 협상을 통해 정식으로 권한을 부여하는 표준 방식이다.
CORS의 동작 방식은 서버가 HTTP 응답 헤더에 Access-Control-Allow-Origin과 같은 특별한 헤더를 포함시켜, 어떤 출처에서 리소스에 접근할 수 있는지를 명시적으로 선언하는 것이다. 이는 클라이언트 사이드 자바스크립트 코드(예: Fetch API나 XMLHttpRequest)가 다른 도메인의 API를 호출할 때, 브라우저가 이 헤더를 확인하여 요청을 허용할지 차단할지를 결정하게 한다. 따라서 보다 안전하고 유연한 접근 제어가 가능해진다.
JSONP에 비해 CORS는 몇 가지 명확한 장점을 가진다. 첫째, HTTP 메서드를 지원하여 GET 요청뿐만 아니라 POST, PUT, DELETE 등 다양한 요청을 안전하게 수행할 수 있다. 둘째, 에러 핸들링이 표준 HTTP 상태 코드를 통해 정상적으로 이루어지며, 셋째, JSON 데이터만이 아닌 모든 형태의 콘텐츠를 주고받을 수 있다. 이러한 이유로 현대 웹 개발에서는 보안 문제와 기능적 한계가 있는 JSONP보다 CORS를 표준으로 채택하고 있다.
6. 역사
6. 역사
JSONP는 2005년에 Bob Ippolito가 제안한 기술이다. 당시 웹 브라우저는 보안상의 이유로 동일 출처 정책을 강력히 적용하고 있었는데, 이 정책은 자바스크립트 코드가 자신이 로드된 도메인과 다른 도메인의 데이터를 XMLHttpRequest를 통해 직접 요청하는 것을 차단했다. 이는 웹 애플리케이션이 여러 도메인에 분산된 API를 활용하는 데 큰 장벽이 되었다.
Bob Ippolito는 이러한 제약을 우회할 수 있는 창의적인 방법으로 JSONP를 고안했다. 그 핵심 아이디어는 HTML의 <script> 태그가 동일 출처 정책의 적용을 받지 않고 외부 자바스크립트 파일을 가져와 실행할 수 있다는 점을 이용하는 것이었다. 서버가 평범한 JSON 데이터 대신, 클라이언트가 미리 정의한 함수 호출로 JSON 데이터를 감싼(패딩한) 자바스크립트 코드를 반환하도록 하여, 데이터가 마치 외부 스크립트 파일처럼 로드되고 즉시 실행되게 만든 것이다.
이 기술은 특히 AJAX가 활발히 사용되던 웹 2.0 시대에 빠르게 확산되었다. 구글, 야후 등 주요 기업들의 공개 API들이 JSON 형식의 데이터를 제공하면서, 교차 도메인 요청을 가능하게 하는 간편한 방법으로 JSONP를 널리 지원하기 시작했다. 이를 통해 개발자들은 별도의 서버 측 프록시 없이도 클라이언트 측에서 직접 타사 데이터를 쉽게 통합할 수 있게 되었다.
그러나 JSONP는 본질적으로 보안에 취약한 방법이었다. <script> 태그를 통한 동적 코드 실행 방식은 XSS 공격에 노출될 위험이 컸으며, 서버가 악의적인 코드를 반환할 경우 이를 제어하기 어려웠다. 이러한 보안 문제와 기술적 한계로 인해, JSONP는 이후 등장한 표준화된 교차 출처 리소스 공신 방법인 CORS에 의해 점차 대체되어 갔다.
