2011-08-04 4 views
4

API를 빌드하고 호출을 사용하는 도메인을 추적하는 방법에 대한 질문이 있습니다.AJAX를 통해 서버에서 PHP 파일을 호출하는 도메인 얻기

API 호출은 PHP로 작성되었으며 인증이 필요하지 않습니다. 사용자는 자신의 서버에서 AJAX 호출로 API를 사용할 가능성이 큽니다.

예를 들어 API PHP 파일을 제공하는 도메인은 dev.yourmapper.com입니다. 도메인 www.metromapper.org의 누군가는 Google지도를 만드는 페이지를 만들고 Ajax를 사용하여 내 파일을 호출하여지도에 데이터를 오버레이합니다. HTTP_REFERER 가능성이 높습니다 http://www.metromapper.org/example/apitest.htm

합니다 (yourmapper.com 스크립트에 사용할 수있는 모든 PHP 서버 변수의 팝업을 볼 수있는 중앙지도 아이콘을 클릭합니다.)

참고 : 여기에

행동에서 그 예이다 링크를 클릭하면 'stackoverflow.com'이됩니다. 링크를 잘라내어 붙여 넣으면 빈 상태가됩니다. referer는 metromapper.org가 될 것이라고 생각합니다. 도메인은 yourmapper.com 스크립트를로드 한 후에 호출하기 때문에 도메인은 분명히로드되지 않습니다.

결론 : 자바 스크립트로 yourmapper.com 스크립트를 호출하는 도메인을 결정하는 데 사용할 수있는 방법은 무엇입니까? 필요한 경우 PHP 외에 다른 언어를 사용할 수 있습니다. 감사.

+0

누군가가 남긴 댓글에서 마커 팝업에서 볼 수있는 REMOTE_HOST 및 REMOTE_ADDR을 사용하도록 제안했습니다. 이것이 Google의 IP 주소 인 것으로 밝혀졌습니다. 내 IP 주소는 yourmapper.com 데이터가 Google에 의해 처리되기 전의 주소입니다. http://whatismyipaddress.com/ip/74.125.75.3 따라서 원래 페이지의 IP/도메인을 가져올 수 없을 수도 있습니다. –

+0

위의 내용은 API가 서버에서 호출되었는지, 아니면 (예 : JSONP를 통해 페이지를 제공 한 서버를 우회합니다.) 후자의 경우 자바 스크립트가있는 페이지 URL ('window.location')을 아약스 호출에 추가 할 수 있습니다. –

+0

@ chris-carson dev.yourmapper.com의 내 API는 metromapper.org와 같은 모든 사람의 웹 페이지에서 호출 할 수 있습니다. API는 데이터를 JSON으로 제공 할 수 있지만이 경우지도에 직접 오버레이하기 위해 KML로 제공됩니다. 다른 사용자의 자바 스크립트 코드를 제어 할 수 없기 때문에 KML 요청에 window.location을 추가하도록 강요 할 수 없습니다. –

답변

3

실제로 잘못된입니다

를 "나는 그것이로드 한 후 해당 도메인이 yourmapper.com 스크립트를 호출하기 때문에 리퍼러가, metromapper.org 것이라고 생각합니다." 첫째, HTTP_REFERER는 대부분의 브라우저가 아닌 자발적인 매개 변수이므로 스푸핑 될 수 있으므로 HTTP_REFERER에 의존해서는 안됩니다. 내가 원하는 경우 참조가 whitehouse.gov 인 것처럼 보이게하는 CURL을 사용하여 웹 사이트 요청을 보낼 수 있습니다. 거기에 보안 조치가 없습니다.

그렇습니다. 브라우저는 해당 매개 변수를 사용자를 현재로드 된 페이지로 참조하는 페이지로 설정합니다. 스크립트가 아닙니다. 그래서 사용자가보고있는 결과를 보는 이유는 사용자가 metromapper.org에 linkoverflowflow.com의 링크로 참조 되었기 때문입니다.

마지막으로 맛있는 부분을 봅시다. JS를 사용하여 브라우저에서 항목을 코딩합니다. 괜찮습니다. 그리고 아무런 문제가 없습니다. 하지만 JS는 오픈 소스라는 사실을 기억해야합니다. 따라서 사람들은 자신의 API를 가지고 놀 수있는 코드를 엉망으로 만들 수 있습니다. 그렇게 말하고있다. 최선의 방법은 JS API의 요청과 함께 사이트의 URL을 전달하는 것입니다. 스크립트를 사용하는 사이트를 "추적"하는 가장 좋은 방법입니다. 서버 측에서 URL이 전달되었는지 확인할 수 있습니다. 그러면 사람들이 API를 수정하여 URL을 서버로 전송하는 비트를 제거하지 못하게됩니다. 그러나 다른 사람의 URL이나 등록되지 않은 임의의 URL을 매개 변수로 사용하도록 수정하지 못하게합니다.

물론 서버에서 실행되는 PHP API를 빌드 할 수 있습니다. JS API는 PHP API에 연결하고 PHP API는 zend-guard로 인코딩되어 있지만 다른 소스 보호 코드 시스템에서는 여전히 코드를 디코딩하여 소스로 돌아가서 혼란 스러울 수 있습니다. 그렇게 할 수있는 사람이 훨씬 적다는 것을 인정하면 일반 사용자는 API를 그대로 사용하게됩니다. 또한 인코딩 된 PHP 파일을 실행할 수없는 서버에서 API를 실행할 수 없다는 문제가 있습니다.

마지막으로 원하는 보안 및 인증 수준을 결정해야하지만 클라이언트 브라우저에서 JavaScript가 JavaScript로 실행 중이므로 난독 화를 넘어서 거의 활용할 수 없습니다.

귀하의 최선의 선택은 JS 코드가 현재 페이지의 URL을 방해하여 API 요청으로 전송하는 것입니다. 여기에서 서버가 URL을 처리하여 루트 도메인과 저장할 정보를 얻을 수 있습니다.

다른 사용자의 웹 사이트 URL에 대한 요청을 "스푸핑"하지 않으려면 특정 위치의 사용자 서버에 PHP API를 구현할 수 있습니다. 예 : http://www.domain.com/my-app-name.php

모든 JS API 호출은 해당 스크립트를 통과해야합니다. 사용자가 API를 다운로드하면 웹 사이트 URL 및 기타 정보를 입력해야합니다. 귀하의 시스템은 "키"를 생성하고 포장하기 전에 스크립트에 삽입하여 다운로드합니다. 이 키는 자신의 도메인에서 유효하며 복어 또는 다른 양방향 암호화 알고리즘을 사용하여 API로 /로부터 모든 전송을 인코딩하는 데 사용됩니다. 이렇게하면 API가 PHP API 파일에서 요청을 받으면 요청한 페이지의 URL을 얻게됩니다.이 요청은 귀하와 해당 사이트의 관리자 만 가지고있는 키로 인코딩됩니다. 따라서 요청은 다음과 같이 처리됩니다. metromapper.org/api?site=[url_encoded_page_address] & req = [encrypted_request]

서버는 페이지 암호를 사용하여 데이터를 해독하는 데 사용해야하는 키를 결정합니다. 그런 다음 데이터를 암호 해독합니다. 데이터가 손상되었거나 예상 한대로 해독되지 않으면 유효하지 않은 요청이므로 아무 것도 반환하지 않고 종료해야합니다.

JS에 암호화를 쓰는 것과는 대조적으로 PHP 파일을 암호화에 사용하는 것이 좋습니다. 왜냐하면 암호화/해독의 부하로 클라이언트 (각 사이트 방문자)에게 부담을주고 PHP를 사용할 필요가 없기 때문입니다. JS보다 훨씬 빨리 처리 할 수 ​​있습니다. 라이브러리가 당신을 위해 이러한 작업을 처리하도록 만들어 졌기 때문입니다.

언제든지 올바른 사이트에서 API에 대해 다른 사이트에 대한 요청을 추적하고 확인할 수 있어야합니다.

+0

의견 및 훌륭한 아이디어에 감사드립니다. HTTP_REFERER 정보 예, 스푸핑 될 수 있음을 알고 있지만 보안 또는 스푸핑보다 사례의 90 %를 추적하는 것이 더 중요합니다. JS와 동일합니다. JSON API 호출이 도메인을 통과한다는 것을 사용자에게 알릴 수 없습니다. 나는 할 수 있지만 최후의 수단이다. REFERER보다 훨씬 쉽게 변경할 수 있습니다. 그러나 나는 이것이 최후의 수단이라고 생각할 것이다. 사람들이 모든 전화를 거는 PHP 파일을 서버에 넣을 것을 요구할 수는 없습니다. 하나 들어, 대부분의 서버는 PHP를 사용하지 않지만 또한 너무 복잡합니다. –

+0

마지막 아이디어는 가장 가능성있는 해결책입니다. 암호화 된 키를 생성하게하십시오. 그러나 문제는이 키가 원본을 보는 사람에게 명백하게 (사이트 변수와 함께) 볼 수 있다는 것입니다. 그렇다면 그들은 누군가 그것을 잘라내어 붙여 넣을 수 있습니다. 난 그냥 REMOTE_HOST IP 주소로 가서 다음 그 도메인을 즉시 발견 할 수있을 것 같아요. 이것은 KML의 Google 서버 문제를 해결하지 못하므로 별도로 알아야 할 것입니다. –

+0

그래, 그 열쇠에 대한 제안은 당신이 그들의 서버에서 PHP 파일을 사용한다고 가정했다. 키는 모든 방문자가 볼 수있는 JS 코드가 아닌 일반 텍스트 서버 측에만 저장되기 때문에 핵심 시스템을 사용하는 것은 사람들이 코드를 수정하여 수집 된 데이터를 무효화하지 못하도록하는 유일한 방법입니다. 요청이 실제로 사이트에서 왔는지 (그리고 JS 코드를 수정 한 사람이 아닌지) 확인할 수있게하기 때문입니다. JSP/ASP에 작은 API 파일을 코딩 할 수도 있습니다. 그러면 더 널리 지원 될 것입니다. – Brian

1

도메인 이름을 기반으로 해시를 생성하고 API 사용자가 요청할 때마다 도메인 이름과 해시를 보낼 수 있습니다. 이제 API를 사용하기 때문에 헤더의 어딘가에 'Access-Control-Allow-Origin'을 설정해야합니다. PHP에서이 작업을 수행하면 조금만 돌아 다닐 수 있습니다. 아래 스크립트는 호출자 측 (API를 사용하는 도메인)에서 PHP가 필요없는 구현의 간단한 예입니다.

발신자 사이드 (NO PHP 필수) :

<script type="text/javascript"> 
    function callA() { 
    var xhttp = new XMLHttpRequest(); 
    xhttp.open("GET", "//ajaxdomain.com/call.php?"+ 
         "dom=www.callerdomain.com&"+ 
         "key=41f8201df6cf1322cc192025cc6c5013", 
       true); 
    xhttp.onreadystatechange = function() { 
     if(xhttp.readyState == 4 && xhttp.status == 200) { 
     handleResponse(xhttp.responseText); 
     } 
    } 
    xhttp.send(); 
    } 
</script> 

아약스 서버 측 (PHP) :

<?php 
    if($_GET['key']==md5($_GET['dom']."Salt")) { 
    header("Access-Control-Allow-Origin: http://".$_GET['dom']); 
    } 
?> 

호출이 악의적 인 도메인에서 온 경우 헤더도 배치 될 것이다이 방법은, 그러나 크로스 원점 예외로 인해 휴식을 취할 수 없으므로 결과가 제공되지 않습니다.

이 예제에서는 md5 해시를 사용했지만, 원하는 경우 더 복잡한 해시를 사용할 수 있습니다. 사용 된 소금은 (항상 그렇듯이) 보관해야합니다.

저는 아래의 (하위) 도메인에서 온라인으로 작업 예제를 작성했습니다. 페이지는 동일합니다.

cors1.serioushare.com - 'CORS 1'버튼에서만 작동합니다.
cors2.serioushare.com - 'CORS 2'버튼에서만 작동합니다.

관련 문제