HTML, ASP, PHP, JAVASC | ||||
|
HTML은 웹상에 원하는 내용을 볼 수 있게 해주는 마크업언어(markup language)입니다. * markup이란 일반 문장 에 <*xxxxx*>이 붙어 있는데 <*xxxxx*>을 markup이라 부릅니다. HTML로는 웹 브라우져 상에서 필요한 글이나 사진들을 표현하여 보여줄 수 있으나 프로그래밍은 불가능합니다. 여기서 프로그래밍이라는 것은 if문장과 같은 조건 문이나 for,while과 같은 반복문을 사용할 수 없다는 것입니다. 이러한 HTML의 단점을 극복하기 위해 만든 언어가 javascript입니다. Javascript는 HTML문장과 섞여 사용하며서 프로그래밍을 할 수 있도록 해줍니다. 프로그램의 문법이 java와 매우 유사하다고 해서 javascript라고 부릅니다. 그러나 Javascript도 결정적인 단점이 있는데 javascript가 HTML과 혼용되어 웹브라우져 상에서 작동되기 때문에 소스가 모두 공개된다 는 것입니다. 우리가 웹브라우져 상에서 마우스의 두번째 버튼을 누르고 소스보기를 하면 HTML과 javascript를 모두 볼 수 잇습니다. 이런 단점을 극복하기위해 만든 프로그램이 ASP와 PHP입니다. javascript는 웹브라우져가 있는 클라이언트 상에서 작동되지만 ASP와 PHP 는 서버 상에서 작동이 되어 모든 결과를 HTML로 만들어 클라이언트로 보내줍니다. 물론 클라이언트에 있는 웹브라우져는 HTML을 글과 사진으로 변환하여 보여줍니다. 이런 이유로 Javascript를 클라이언트 사이드 프로그래밍이라 부르고 ASP와 PHP를 서버 사이드 프로그래밍이라 부릅니다. ASP와 PHP의 차이점으로는, ASP는 문법이 BASIC언어와 유사한 반면,PHP는 C언어와 매우 유사합니다. |
![]() |
||
??? |
![]() |
| ||||||||
이런 질문이 앞서도 몇개 나온 거 같은데.. 다음글을 읽어보세요. HTML, PHP, JSP 의 차이점인데.. ASP와 JSP는 실행방식이 비슷합니다. 컴파일된 형식만 다를 뿐이죠. 그러니 JSP를 ASP라고 생각하시고 읽으시면 됩니다. HTML, PHP, JSP... 그리고, JavaScript는 이 3언어와 다른 방식의 언어이죠. 글을 하나 더 드릴께요. 이 글은 JSP와 JavaScript의 차이점을 설명하는 글인데, ASP와 JavaScript의 차이라고 생각하셔도 별 차이가 없습니다. JSP와 ASP는 모두 서버측 동적 문서이거든요. JSP and JavaScript 위의 글에서도 알수 있지만, javascript는 클라이언트에서 실행되는 언어이고, JSP나 PHP,ASP 등은 서버에서 실행되는 서버 스크립트 언어입니다. 컴파일되고 실행이 되는 위치에서 차이가 나는 것이죠. 그리고 참고로 자바 애플릿(Java Applet)이라는 것이 있는데, 이는 javascript와 약간 다릅니다. 자바 애플릿은 애플릿형태의 완전한 자바 프로그램입니다. 그렇기 때문에 자바로 표현할 수 있는 무척 다양한 형태의 기술을 브라우저를 통해서 보일 수 있죠. 이도 클라이언트의 브라우저에서 실행됩니다. 자바 서블릿(Java Servlet)이라는 것이 있는데요. 이것은 JSP와 비슷한 개념입니다. 사실 자바 서블릿을 조금 더 쉽게 하기 위해서 JSP라는 것을 만들었거든요. (JSP는 서버에서 서브릿으로 컴파일됩니다.) 따라서 PHP,ASP와 같이 서버에서 실행되는 프로그램입니다. from debussy-min. |
![]() |
| ||||||||
HTML, ASP, PHP의 기능을 설명하기 위해서는 먼저 설명할게 있습니다. 바로 MY SQL 과 SQL 이죠. 서버를 사용하실때 그 서버운영체제가 리눅스이면 MY SQL을 쓰시게 되는겁니다. MY SQL을 통해 DB를 사용하고, 또 다른것을 이용하실때 쓰는것입니다. 그리고 윈도우 2000이라면 SQL이죠. SQL,MY SQL을 HTML로 옮길수 있을까요? 못 옮깁니다. SQL을 HTML로 옮기고 싶으실때 쓰는것이 ASP 입니다. 기능은 HTML의 기능과 똑같습니다. 다만 다른것이 있다면 SQL과 연결을 시켜준다는 것이죠. 그리고 MY SQL역시 HTML로 연결을 못시킵니다. 그때 쓰는것이 PHP입니다. PHP를 통해서 연결을 시켜주는 것입니다. 이것 역시 HTML과 ASP와 다를게 없습니다. 다만 MY SQL을 연결시켜 준다는 것일뿐 입니다. 한마디로 HTML, ASP, PHP의 기능은 같다입니다. 다만 MY SQL이나 SQL을 넣고 싶다면 ASP나 PHP를 써야한다는 점입니다. 그리고 자바스크립트에 대해 알려드리겠습니다. HTML과 함께 사용할 수 있는 언어를 스크립트 언어라고 합니다. 스크립트 언어에는 대표적으로 자바(Java)언어와 유사한 자바스크립트(Java Script)와 비주얼베이직(Visual Basic)와 유사한 비주얼베이직스크립트(VB Script)가 있습니다. 그중 가장 많이 쓰이는 것이 자바스크립트 랍니다. 또한 효과를 위해 스타일쉬트(Style Sheet / CSS)도 많이 사용하는데 이런것들을 이용해 HTML에 생명을 불어넣는 것을 DHTML(Dynamic HTML : 동적 HTML)이라고도 합니다. 자바스크립트를 이용하여 우리는 달력도 만들 수 있고 작은 게임정도도 만들 수 있으며 주민등록번호 체크 또는 수치 계산 등 까지 할 수 있습니다. 많은 도움이 되셨길 바랍니다. |
'Web > Info' 카테고리의 다른 글
애플릿이란? [출처] 애플릿이란?|작성자 희정 (0) | 2009.01.12 |
---|---|
서블릿 (0) | 2009.01.12 |
Servlet(http://kmh.ync.ac.kr/encycl/terms/termsJ/jsp2.htm) (0) | 2009.01.12 |
무료 웹호스팅 000webhost.com (1.5GB 용량, 100GB 트래픽) 웹사이트 소개 & 활용 (0) | 2009.01.12 |
웹 종류 (0) | 2009.01.10 |
Java 애플릿(applet)이 인터넷 상의 클라이언트측에서 실행되는 작은 프로그램인데 반해서 Java 서브릿(servlet)은 클라이언트의 요청을 처리해 주기 위한 서버측에서 실행되는 작은 프로그램(server side applet)이다.
클라이언트의 요청에 따라 서버에서 동적으로 실행될 필요가 있는 프로그램들을 CGI (Common Gateway Interface)라고 하는데, 서브릿은 CGI를 대체하는 요소로 사용될 수 있다. 즉, 서버에서 실행되는 Java 가상머신을 이용하면, CGI 프로그램들을 Java 언어로 구현할 수 있다.
Java 서블릿의 장점은 CGI 응용 프로그램보다 더 빠르게 실행될 수 있다는 것이다. CGI에서는 각 클라이언트의 요청에 대하여 별도의 프로세스가 생성되지만, 서블릿은 하나의 디몬 프로세스(daemon process) 내에서 스레드(thread)로 호출되기 때문에 클라이언트의 요청에 따른 서버측의 오버헤드가 적다는 것을 의미한다.
서블릿servlet은 "동적 컨텐트를 생성하는 웹컴포넌트"로 정의되어 있다.
자바 프로그래밍 입장에서 보면 서블릿은 javax.servlet.Servlet 인터페이스를 이행하는 자바클래스이다.
자바 서블릿은 사용자가 정의한 범용 서블릿(GenericServlet 을 확장한 클래스)일 수도 있지만, 대부분은 HTTP 프로토콜 서비스를 지원하는 javax.servlet.http.HttpServlet 을 확장한 http 서블릿이다.
2진코드로 컴파일된 서블릿은 웹서버에 동적으로 탑재되어 그 웹서버에 의해(엄격하게는 서블릿 컨테이너에 의해) 실행된다.
서블릿은 서블릿 컨테이너에 의해 이행되는 요청/응답(request/response) 패러다임을 통해 웹클라이언트(웹브라우저), 즉, 사용자와 상호작용한다.
컨테이너란 뭔가 담는 그릇이다. GUI 컨테이너는 GUI 컴포넌트를 담는 그릇인 것처럼, 서블릿 컨테이너는 서블릿이라는 웹 컴포넌트를 담는 그릇이다.
GUI 컨테이너가 단지 GUI 컴포넌트를 부착하는 그릇 구실만 하는 것이 아니라, 그 부속 컴포넌트들의 그리기와 작동을 관리하는 것처럼, 서블릿 컨테이너 역시 서블릿을 담는 역할 이상의 것을 수행한다.
■ 서블릿 컨테이너의 역할
서블릿 컨테이너는 다음과 같은 역할을 수행한다.
기본적으로 서블릿 컨테이너(servlet container)는 서블릿을 담는 그릇 역할을 한다. 즉, 서블릿 코드를 저장하는 저장장소 역할을 한다는 것이다.
서블릿 컨테이너는 서블릿의 탑재, 인스턴스화 및 초기화 등 서블릿의 생명주기를 관리한다.
서블릿 컨테이너는 웹서버 혹은 애플리케이션 서버와 결합되어 요청/응답(request/response) 패러다임에 따라 네트워크 서비스를 제공한다. 보다 구체적으로 MIME 기반 요청을 디코드(decode)하고 MIME 기반 응답을 구성(format)한다.
■ 서블릿 컨테이너의 설치
서블릿 컨테이너는 호스트 웹서버(혹은 애플리케이션 서버)에 직접 구축하거나, 혹은 그 서버의 고유 확장 API를 통해 웹서버에 부착 컴포넌트 형식으로 설치되기도 한다.
그 자체로 서블릿 컨테이너 역할을 포함하는 Java Web ServerTM 가 전자의 예이고, Apache 웹서버에 Tomcat 을 서블릿 컨테이너로 설치하는 것이 후자의 예이다.
■ 서블릿 컨테이너의 조건
서블릿 컨테이너는 요청/응답 프로토콜로 최소한 HTTP/1.0 을 지원해야 하며, HTTP/1.1 지원을 강력하게 권고하고 있다.
경우에 따라서는 HTTPS(HTTP over SSL)을 기반으로 하는 요청/응답 프로토콜을 지원할 수도 있다.
■ 서블릿 컨테이너의 보안 처리
서블릿 컨테이너는 서블릿 실행 환경에 보안 제약을 가할 수 있는데, 이 보안 기능은 Java 2 플랫폼(Java 2 SDK)에 정의된 허용 아키텍처를 사용해야 한다.
스윙 애플리케이션의 케이스 역할을 하는 JFrame 은 다음과 같은 최소한의 요소들로 구성된다.
제목막대
몸체
경계선
JFrame 은 스윙 애플리케이션의 가장 기본 컴포넌트이므로 그 애플리케이션의 제목과 몇몇 기본 기능을 제어하기 위한 요소들이 부착된다.
스윙을 포함한 GUI용 애플리케이션의 기본 기능이란 그 윈도우를 숨기고(아이콘화iconization: MS Windows 등에서 주 윈도우의 제목막대에 부착된 숨기기 아이콘 을 누르면 작업표시줄(task bar)에 아이콘으로 바뀐다는 것을 알 수 있다.), 창 크기를 최대화하고(MS Windows 에서 누르기), 애플리케이션을 끝내는 것(MS Windows 에서 누르기) 등이다.
결국 JFrame 제목막대에 부착될 수 있는 것은 다음과 같다.
제목
윈도우 제어 버튼
아이콘화 버튼
최대화 버튼
창닫기 버튼
여기 프레임의 제목막대에 붙은 요소들도 따지고 보면 컴포넌트이지만 사용자가 따로 만들어서 붙일 것 없이 JFrame 자체에 디폴트로 부착되는 것이므로 별도의 컴포넌트로 분류하지 않는다.
■몸체
JFrame 의 몸체는 말 그대로 스윙 애플리케이션의 각종 컴포넌트들이 부착될 부분이다. 그렇다고 JFrame 의 몸체가 꼭 눈에 보이는(가시화 된) 특정 영역을 가진다는 것을 뜻하지는 않는다. 이미 알아본 바와 같이 스윙에서 컴포넌트는 프레임에 직접 부착하는 것이 아니라 JRootPane 에 부착한 뒤 이를 프레임에 부착하고, JRootPane 은 눈에 보이지 않는 창유리 같은 것이므로 외형적으로는 뚜렷한 경계가 없을 수도 있다. 이런 점에서 보면 JRootPane 이 JFrame 의 몸체 부분이라 볼 수도 있다.
■경계선
경계선은 말 그대로 JFrame 전체가 차지하는 영역의 경계를 나타내는 선으로 단순히 추상적인 선일 수도 있고, 구체적으로 가시화 한 실질적인 선일 수도 있다.
servlet 이라 하면 애플릿(applet)을 연상해 볼 수 있다. 또한 servlet 이라는 용어에서 이것이 서버와 관련되어 있다는 것을 알 수 있다.
영어 접미어 let 은 "작은"이란 뜻이다. 그러므로 applet 은 작은 애플리케이션(application)이란 뜻으로 붙인 명칭이고, servlet은 서버측에서 돌아가는 작은 프로그램이란 뜻으로 붙인 명칭이다.
한 마디로 서블릿과 웹서버와의 관계는 애플릿과 웹브라우저와의 관계에 대응된다고 볼 수 있다.
모든 네트워크 프로그램은 클라이언트 측 프로그램과 서버 측 프로그램의 쌍으로 이루어진다. Web 의 경우도 웹 자원을 요청하는 클라이언트 측 프로그램인 웹브라우저(web browser)와 웹 서비스를 제공하는 웹 서버가 쌍을 이룬다. 따라서 "서블릿과 웹서버와의 관계는 애플릿과 웹브라우저와의 관계에 대응된다"는 것은 서블릿과 애플릿이 모두 웹과 관련되며, 애플릿은 클라이언트 측 프로그램이며 서블릿은 서버 측 프로그램이라는 것을 알 수 있다.
애플릿과 서블릿의 차이
애플릿이 클라이언트 측 웹프로그램이며 서블릿은 서버 측 웹프로그램이라는 차이점 외에도 또 다른 큰 차이는 애플릿은 그래픽 사용자 인터페이스(GUI)를 지원하는 반면, 서블릿은 GUI를 지원하지 않는다는 점이다. 이 즉 실행 결과만 전달하는 서블릿의 특성으로 볼 수 있다.
애플릿과 서블릿의 타 네트워크 프로그램과의 차이
애플릿과 서블릿의 타 네트워크 프로그램과의 차이는 일반적으로 클라이언트 프로그램은 (플러그인 형식으로) 클라이언트 측 기계에 설치되고 서버 프로그램은 서버 측 기계에 설치되는데, 애플릿과 서블릿은 모두 그 소스가 서버에 포함되어 있다는 점이다.
그 이유는 웹브라우저상에서 돌아가는 애플릿의 특성상 웹브라우저(사용자)가 URL 을 통해 웹서버에 애플릿 자원을 요청하면 (Applet 태그를 통해) 웹 서버는 애플릿 2진코드(컴파일 된 애플릿 클래스)를 웹브라우저(클라이언트)에 전달하고 클라이언트는 다만 그 실행만 담당하기 때문이다.
'Web > Info' 카테고리의 다른 글
애플릿이란? [출처] 애플릿이란?|작성자 희정 (0) | 2009.01.12 |
---|---|
서블릿 (0) | 2009.01.12 |
HTML, ASP, PHP, JAVASC (지식카페 퍼옴) (0) | 2009.01.12 |
무료 웹호스팅 000webhost.com (1.5GB 용량, 100GB 트래픽) 웹사이트 소개 & 활용 (0) | 2009.01.12 |
웹 종류 (0) | 2009.01.10 |
Ajax와 XML: 다섯 개의 추천할 만한 Ajax 위젯 (한글)
난이도 : 중급
Jack D Herrington, Senior Software Engineer, Leverage Software Inc.
Web 2.0은 사용자 경험을 강조하고 있습니다. 이것의 일환으로 고급스러운 방식으로 사용자와 인터랙팅 하고 사용자에게 정보를 제공하는 것입니다. 이러한 새로운 인터페이스들을 위젯이라고 하며, Asynchronous JavaScript + XML (Ajax)을 사용하여 서버와 통신합니다. 사이트와의 상호 작동을 향상시키는데 사용할 수 있는 다섯 개의 위젯에 대해 알아봅시다.
Web 2.0 혁명은 웹 사이트 상에서 고객과 상호 작동하는 독특하면서도 고급스러운 방식이 탄생했다.
SWF/Charts 위젯부터 설명하겠다. 내가 생각하기에 이 위젯이 전개하기에 가장 쉽다. "한편의 그림이 천마디 말보다 낫다"라는 속담을 무시할 수 없으며 특히, 그래프가 관여된 XML로 인코딩 된 데이터를 그릴 수 있는 위젯이 있다면 정말 좋을 것 같지 않은가? 마침 Listing 1. Chart_page.html
Charts.swf 는 두 개의 매개변수를 취한다. 라이브러리 디렉토리의 위치와 XML 데이터의 Listing 2. Chart_data.xml
이 파일은 차트용 데이터이고, 선택적인 비주얼 정보도 있다. 이 경우, 필자는 차트 유형을 Firefox 브라우저에서 파일을 검색하면 그림 1과 같은 그래프를 볼 수 있다. 그림 1. Chart Widget ![]() 기본 컬러 스킴과 모습도 멋지며, 그래프는 중심축 값을 보기 좋게 처리했다. 적은 노력으로 분명히, graph_data.xml 파일을 동적인 웹 페이지로 대체할 수 있었다. 리턴된 데이터가
데이터를 나타내는 또 다른 방법은 게이지로 표현하는 것이다. 개인적으로는 게이지에 하지만, 웹이 간단한 바 차트도 잘 수행하지 못한다면, 원형 게이지 역시 수행할 수 없다. SWF게이지 위젯을 삽입하는 HTML 페이지로 시작하겠다. (Listing 3) Listing 3. Gauge_page.html
gauge.swf 영화는 하나의 인자를 취한다. 데이터의 위치이다. 이 경우, 그 위치는 Listing 4. Gauge_data.xml
여러분도 보듯, SWF는 이 위젯에 다른 방식을 취했다. 게이지(또는 그래프)용 데이터를 솔직히, 필자는 데이터를 제공할 수 있는 기본 게이지를 선호한다. 하지만, 이 방식도 내 브라우저에 있는 페이지로 갈 때, 그림 2와 같은 게이지를 볼 수 있다. 그림 2. Gauge Widget ![]() 그래픽 프리머티브를 지정하는 것으로는, 이 위젯에서 얻을 수 있는 것이 많이 없다고
사용자들은 이제 데스크탑 애플리케이션에서 In-place editing을 기대하지만, 이러한 기능은 In-place editing을 구현하려면, 직접 작성하거나, JavaScript 프레임웍들 중 하나를 In-place editing용 HTML 테스트 파일은 Listing 5를 참조하라. Listing 5. Inplace.html
Inplace.html에는 필요한 모든 JavaScript 소스 파일이 포함된다. 간단한 테이블에 In-place
Listing 6은 submitted.html 파일이다. Listing 6. Submitted.html
이제 테스트 할 차례이다. 브라우저를 HTML 파일에서 연다. 이곳에서 원래의 텍스트를 그림 3. in-place editing의 시작 포인트 ![]() 노란색 하이라이팅은 이것을 클릭하여 필드를 편집할 수 있다는 사용자용 인디케이터이다. 그림 4. 클릭한 후 텍스트 편집하기 ![]() 텍스트를 수정하고 ok를 클릭한다. 이렇게 하면 데이터가 서버에 게시된다. (또는 이 경우 그림 5. ok를 클릭한 후 새로운 콘텐트 ![]() 이와 같은 간단한 인터페이스 업그레이드는 애플리케이션의 가용성에 차이를 만든다.
브라우저에서 윈도우를 웹 페이지에 구현하기 힘들다는 것은 좋은 일일지도 모른다. 하지만 어쨌든, 내가 말했지만 Dynamic HTML (DHTML) 페이지용 윈도우를 구현하는 것은 쉬운 Listing 7. Window.html
prototype.js와 window.js 소스 파일을 헤더로 가져온다. 그런 다음, 내가 좋아하는 매개변수 이 경우 필자는 terms.html 파일을 참조한다. (Listing 8) Listing 8. Terms.html
내 브라우저에서 이 페이지를 실행하면 그림 6과 같은 윈도우를 보게 된다. 그림 6. 초기 윈도우 ![]() 이것은 단지 두 개의 Mac 윈도우만은 아니다. Mac 처럼 보이는 DHTML 윈도우가 있고 그 윈도우를 늘려 이동할 수 있다. (그림 7) 그림 7. 이동 및 크기 조정 후 윈도우 모습 ![]() 필자는 본 기술자료와 내 작업을 위해 여러 드물 윈도우 라이브러리를 검토했고, 이것이
많은 사용자 인터페이스(UI)를 다루어본 사람이라면 실제 상태를 나타내는 것이 중요하다고 carousel 컨트롤은 고정된 공간에서 여러 이미지들을 보여준다. 이미지 블록의 왼쪽과 공간 절약은 중요하다. 세 개의 공간에 30 개의 앨범 커버를 넣을 수 있고, 각각 알맞은 크기 carousel의 단점은 구현이 쉽지 않다는 점이다. 특히, 이것의 특징 중 하나가 왼쪽 또는 필자는 웹 페이지에 간단한 carousel 위젯을 구현했다. ( Listing 9) Listing 9. Carousel.html
이전 예제들 보다 방대하다. 하지만 코드 대부분이 그래픽을 설정하고 서버에서 리턴된 Ajax 이 carousel용 데이터는 Listing 10에 나와있다. Listing 10. Data.xml
이 경우, 파일은 그림 8. 이미지 carousel ![]() 이미지를 클릭하고 그 이미지가 있는 페이지로 갈 수 있다. (또는 내가 지정한 URL로 간다.)
웹 상에서 사용할 수 있는 무료/상용 위젯과 툴들을 소개했다. 이 글을 쓰면서 보았던 많은
WYSIWYG 에디터 외에도, 프로그래스 바, 탭 다이얼로그 박스, 아코디언 컨트롤, 클락, 데이트 피커(date picker), RSS, Outline Processor Markup Language (OPML) 리더용 솔루션도 있다. 심지어 대화형 터미널 윈도우용 솔루션도 있다. DHTML
교육
제품 및 기술 얻기
토론
|
[출처] Ajax와 XML: 다섯 개의 추천할 만한 Ajax 위젯 (한글)|작성자 파워홍
'Web > ajax' 카테고리의 다른 글
ASP.NET AJAX를 지원하지 않는 웹호스팅에 AJAX 사용하기 닷넷 (0) | 2009.01.12 |
---|---|
Ajax와 XML: 최고의 Ajax 배우기 (한글) (0) | 2009.01.12 |
php java ajax 웹프로그래밍 기술서 출처 (0) | 2009.01.12 |
[IBM 디벨로퍼웍스] Ajax로 SOAP 웹 서비스 호출하기, Part 1: 웹 서비스 클라이언트 구현하기 (한글) [출처] [IBM 디벨로퍼웍스] Ajax로 SOAP 웹 서비스 호출하기, Part 1: 웹 서비스 클라이언트 구현하기 (한글) (0) | 2009.01.12 |
Teodor Zlatanov
프로그래머, Gold Software Systems
2002년 1월
보다 나은 펄(Perl) 프로그래밍을 위한 완벽한 가이드를 제공하고 있다. 이번에는 객체 지향 프로그래밍(OOP, Object Oriented Programming)에 대해 설명한다. 객체 지향 프로그래밍이 무엇이고, 언제 쓰이며, 펄에서는 어떻게 작용하는지를 설명할 것이다.
객체 지향 프로그래밍(Object Oriented Programming, OOP)
OOP는 프로그래밍 방식 또는 문제를 해결에 쓰이는 일반적인 접근방식이다. 절차적 프로그래밍과 함수 프로그래밍 방식과는 연관성이 적고, 그들과 잘 맞지 않는다.
이 글에서는 펄에서 OOP와 함수적/절차적 프로그래밍의 기초를 다루겠다. 그리고 펄 프로그램과 모듈에서 OOP를 사용하는 방법을 설명하겠다. 이 글은 요약에 그칠것이라는 것을 명심하라. 펄 OOP의 모든 부분을 설명하는 것은 무리이다. 그와 같은 것을 다루는 책이 많이 나와있으며 이미 여러차례 다루어졌다.(참고자료).
OOP가 정확히 무엇인가?
OOP는 객체를 사용하여 문제를 해결하는 기술이다. 프로그래밍 용어에서 객체(object)란 속성(property)과 동작(behavior)이 문제 해결에 주요하게 작용하는 엔터티(entity)이다. 정의를 좀 더 자세하게 내려야 하겠지만, 오늘날의 컴퓨터 산업에서 OOP 접근방식의 엄청난 다양성 때문에 불가능하다.
펄 프로그래밍에서, OOP는 필수적인 것은 아니다. Perl version 5 이상 버전은 OOP를 장려하지만 필요한 것은 아니다. 모든 펄 라이브러리는 모듈이다. 적어도 OOP의 기초를 사용한다는 것을 의미한다. 게다가 대부분의 펄 라이브러리는 객체로서 구현된다. 모듈을 사용하는 사람은 특정 작동과 속성을 지닌 OOP 엔터티로서 그들을 사용해야 한다.
기본적인 OO 프로그래밍 언어 특징
일반적으로, OO 프로그래밍 언어에 있어서 기본적인 세 가지의 특징이 있다. 상속(inheritance), 다형성(polymorphism), 캡슐화(encapsulation)가 바로 그것이다.
펄은 상속을 지원한다. 상속(Inheritance)은 하나의 객체(child)가 시작 포인트(parent)로서 다른 것을 사용하고 그런다음 필요할 경우에 속성과 동작을 변경할 때 적용된다. 이러한 자식-부모 관계는 OOP에 있어서 필수적이다. 재사용(reuse)은 OOP의 이점 중 하나이며 프로그래머들도 이러한 특징에 만족한다.
상속에는 두 가지 유형이 있다. 단일 상속(Single inheritance)은 자식이 단 하나의 부모를 가져야 한다. 반면 다중 상속(multiple inheritance) 은 좀 더 자유롭다. 실제로 둘 이상의 부모를 보게 될 경우는 드물지만 펄은 다중 상속을 지원한다.
다형성(Polymorphism)은 한 객체를 다른 것처럼 보이도록 만드는 기술이다. 펄에서, 다형성은 완벽히 지원된다. 펄 프로그래머들은 상속된 동작을 변경하는 것보다는 객체 속성을 가진 일반적인 작동을 변경하는 것을 더욱 선호하기 때문에 빈번하게 사용되는 것은 아니다. 234 포트의 UDP 패킷 리셉션과 트랜스미션에, 80 포트의 TCP 패킷 리셉션에, 1024 포트의 TCP 패킷 트랜스미션을 위해 세 개의 IO::Socket::INET
객체를 만드는 코드를 기대한다는 것을 의미한다. 첫 번째 경우에는 IO::Socket::INET::UDPTransceiver
를, 두 번째의 경우 IO::Socket::INET::TCPReceiver
를, 세 번째의 경우 IO::Socket::TCPTransmitter
를 사용하는 코드를 기대하기 보다는 말이다.
OOP 순수주의자들은 모든것이 적절하게 구별되어 한다고 느끼지만, 펄 프로그래머들은 순수주의자가 결코 아니다. 그들은 OOP 규칙에 대해 융통성을 발휘하고 있다.
캡슐화(Encapsulation)는 객체 작성자가 액세스를 허용하기를 원치 않는다면 사용자에게 액세스를 불가능하게 하는 방식으로 객체 작동과 속성을 인클로징한다는 것을 의미한다. 그러한 방식으로 객체 사용자들은 하지 못하도록 정해진 일을 수행할 수 없으며, 액세스 할 수 없도록 지정된 것에 액세스 할 수 없다(Listing 1).
왜 OOP가 강력한 방식인가?
어떻게 OOP가 강력한 방식이 될 수 있었는지 생각해보자. OOP에는 절차적/함수 프로그래밍 (PP/FP)에 적용하기에 까다로운 여러 주요 개념들이 있다는 것을 알았다. 우선, 무엇보다도, PP나 FP 모두 상속이나 클래스 다형성 개념이 없다. PP와 FP에는 클래스가 없기 때문이다. PP와 FP에서 캡슐화는 존재한다. 하지만 단지 절차적 레벨에서 존재하는 것 뿐이다. 결코 클래스나 객체 속성으로서 존재하는 것은 아니다. 따라서 프로그래머는 호환되지 않는 방식들을 섞는 것보다 전체 프로젝트에 OOP를 고수하는 것이 낫다.
OOP는 절차적 프로그래밍 방식과 함께 잘 작동하지 않는다. 왜냐하면 OOP는 객체에 집중하고 절차 프로그래밍은 프로시져(procedure)에 기반하기 때문이다. 마치 메소드(method)와 같은 프로시져는 사용자에 의해 호출되는 함수이지만 그 둘 사이에는 차이점이 없다.
프로시져는 객체 데이터를 가지고 있지 않다. 그들은 매개변수 리스트에 있는 데이터로 전달되거나 범위내에서 데이터를 사용해야 한다. 프로시져는 호출 시 이것으로 전달된 모든 데이터나 글로벌 데이터에 액세스 할 수 있다. 메소드는 오직 그들의 객체 데이터에만 액세스 해야한다. 실제로, 메소드용 함수 범위는 메소드를 포함하고 있는 객체이다.
프로시져는 글로벌 데이터를 사용하여 찾는다. 단, 절대적으로 필요할 때만 수행되어야 한다. 글로벌 데이터를 사용하는 메소드는 가능하면 빨리 다시 작성되어야 한다. 프로시져는 다른 매개변수들을 가진 다른 프로시져들을 호출한다. 메소드는 단지 몇 개의 매개변수만을 가지고 있어야 하며 다른 프로시져들 보다 자주 다른 메소드들을 호출한다.
함수 프로그래밍(FP)은 여러가지 이유로 OOP와 잘 섞이지 않는다. 가장 중요한 이유는 FP는 문제를 해결하는 데 있어서 세부적인 함수 접근방식에 기반을 두고 있고, OOP는 개념을 표시하기 위해 객체를 사용한다. FP 프로시져들은 어느 곳에서나 사용될 수 있지만, OOP 메소드는 그것을 보유하고 있는 객체내에서만 사용될 수 있다.
이제는 펄이 OOP, FP, PP 방식들을 섞는 최상의 언어인지를 설명할 수 있다.
펄에서 OOP를 절차적/함수 프로그래밍과 섞는 방법
펄은 프로그래머가 원하는 무엇이든 할 수 있도록 하기위해 길이를 한없이 늘일 수 있다. 이는 Java와 C++ 같은 언어들과는 극명하게 대조된다. 예를 들어, 펄에서 프로그래머는 이전에 선언되지 않는 변수를 자동으로 만들수 있다.
따라서 펄은 여러 방법들을 남용하기에 적합한 언어이다. 내부 객체 데이터에 액세스하고, 클래스를 변경하고, 메소드를 재 정의하는 것이 모두 가능하다. 펄의 규칙은 프로그래머들이 코딩, 디버깅, 실행 효율성에 맞게 규칙을 파괴할 수 있다. 작업을 수행하는데 도움이 된다면 괜찮다. 따라서, 펄 그 자체는 프로그래머에게 베스트 프랜드가 될 수도 최악의 적이 될 수도 있다.
규칙을 위반하는 것임에도 왜 사람들은 OOP, FP, PP를 섞기를 원하는가? 다시 근본적인 문제로 되돌아가 보자. OOP, FP, PP는 무엇인가? OOP, FP, PP는 툴이고 모든 프로그래머들이 하는 첫 번째 작업은 그들의 툴을 이해하는 것이다. 만일 프로그래머가 해시를 소팅할 때 FP Schwartzian 변형을 사용하지는 못하는데 Sort::Hashtable
을 작성할 수 있거나 또는 Sys::Hostname
모듈의 재사용을 실패했지만 대신 시스템의 호스트네임을 얻기 위해 절차 코드를 작성한다면, 그 프로그래머는 시간, 노력, 돈을 낭비한 것이 되고, 코드 품질과 신뢰성도 깎인다.
프로그래밍 팀은 최상이라고 믿고 있는 툴에 만족할 수 있다. 이것은 그들에게 일어날 수 있는 최악의 일이다. 프로그래머는 효율성을 증대시키고, 더 나은 코드를 만들 수 있으며, 팀을 더욱 혁신적으로 만들수 있는 방법이 무엇이든지 그 방법을 섞을 수 있어야 한다. 펄은 이러한 태도를 인정하고 장려한다.
OOP의 효용성
OOP의 효용성을 이 글에서 설명하기에는 너무나 많다. 또한 앞서 언급했듯이 이 주제를 다루는 책들이 많이 있다.
OOP는 기본적인 클래스와 객체에 의존하기 때문에 OO 코드를 재사용한다는 것은 필요할 때 클래스를 임포팅한다는 것을 의미한다. 코드 재사용은 OOP를 사용하기 위한 가장 중요한 이유이고, OOP가 오늘날의 산업에서 중요성과 대중성을 얻을 수 있는 이유이다.
단점도 있다. 예를 들어, 이전 문제에 대한 솔루션이 현재 상황에도 이상적으로 적용되지 않을 수도 있고 형편없이 문서화 된 라이브러리는 이해하고 사용하기가 힘들어 오히려 다시쓰는 편이 더 나을 때도 있다. 시스템 아키텍트의 임무는 이러한 단점을 보완하는 것이다.
코드 품질은 OOP를 이용하여 향상된다. 캡슐화는 데이터 오염문제를 없애기 때문이다. 상속과 다형성은 새로 작성되어야 하는 코드의 복잡성을 줄인다. 코드 품질과 프로그래밍 혁신 사이에는 미묘한 균형이 있고 각 팀은 팀의 목적에 맞게 이것을 활용해야 한다.
OOP의 상속과 재사용은 코드의 일관성있는 인터페이스를 가능하게 한다. 모든 OO 코드가 일관성있는 인터페이스를 갖추어야 한다는 의미는 아니다. 프로그래머는 일반적인 아키텍쳐를 고수해야 한다. 예를들어, 확장이 가능하고 사용하기 매우 편리한 모듈식의 인터페이스를 통해 에러 기록을 위한 포맷과 인터페이스에 팀은 합의를 해야한다. 그때야 비로소 모든 프로그래머는 에러가 많은프린트 문장 대신 인터페이스를 사용한다.
적응성(adaptability)은 프로그래밍을 할 때 다소 막연한 개념이다. 개인적으로는 이것을 환경과 사용 변화의 수락과 예견으로 정의하고 싶다. 모든 소프트웨어는 진화하기 때문에 적응성은 중요하다. 잘 작성된 소프트웨어는 발전해야 한다. OOP는 모듈식의 디자인, 향상된 코드 품질, 일관성있는 인터페이스를 이용하여 새로운 오퍼레이팅 시스템이나 새로운 리포트 포맷이 핵심 아키텍쳐에 급진적 변화를 주어야하는 필요성을 감소시킨다.
펄에서 OOP 사용하기
믿거나 말거나 지만 :) 펄에서 OOP는 초급 이나 중급 레벨이 어렵지가 않다. 고급 레벨의 사용도 복잡하지 않다. 펄은 프로그래머들에게 몇 가지 제한을 둔다.
첫 번째 단계는 펄 패키지를 이해하는 것이다. 패키지는 C++ 과 Java 라이브러리에 있는 네임스페이스(namespace) 같은 것이다. 펄 패키지는 프로그래머에게 자문역할을 한다. 기본적으로 펄은 패키지들 간에 데이터 교환을 제한하지 않는다.
Listing 1. 패키지 이름, 패키지 바꾸기, 패키지들 사이에 데이터 공유, 패키지 변수
|
파일 범위의 어휘 변수인 $extra_sound
는 세 패키지 ("main", "Pig", "Cow")액세스 할 수 있다. 이 예제에서 같은 파일 안에서 모두 정의되었기 때문이다. 일반적으로 각 패키지는 각자의 파일 안에서 정의되고 어휘 변수들은 패키지에 속하게 된다. 따라서 캡슐화가 가능하다. ( "perldoc perlmod
"를 실행해보라.)
다음에는 패키지들을 클래스에 결부시켜야 한다. 펄에서의 클래스는 단지 형식적인 패키지이다. (그와는 반대로 객체는 bless()
함수로 특별하게 만들어졌다). 펄은 OOP 규칙을 융통성있게 적용하여 프로그래머는 규칙에 제약을 받지 않는다.
new()
메소드는 클래스 컨스트럭터용 이름이다. 클래스가 객체로 인스턴스화 될 때마다 호출된다.
|
Listing 2에 있는 코드를 Barebones.pm 파일에 놓고 디렉토리에서 다음을 실행시켜서 테스트 할 수 있다:
|
예를 들어, print 문을 new()
메소드 안에 두어 $classname
변수가 무엇을 포함하고 있는지를 볼 수 있다.
Barebones->new()
대신 Barebones::new()
을 호출하면 클래스 이름은 new()
로 전달되지 않을 것이다. 다시말해서, new()
는 컨스트럭터가 아닌 평범한 함수로서 작동한다.
Y$classname
가 왜 전달되어야 하는지 궁금할 것이다. bless {}, "Barebones";
라고 부르지 않는가? 상속이라는 것 때문에 이 컨스트럭터는 Barebones
에서 상속되는 클래스에 의해 호출되지만 Barebones
라고 하지는 않는다.
모든 클래스는 멤버 데이터와 new()
와는 다른 메소드를 필요로 한다. 이를 정의하는 것은 몇 개의 프로시져를 작성하는 것 만큼 쉽다.
|
이 코드를 다음을 이용하여 테스트 할 수 있다:
|
그러면 결과 '2'를 얻는다. 컨스트럭터는 두 번 호출되고 Barebones
객체 범위가 아닌 Barebones
패키지 범위로 한정된 어휘 변수($count
)를 수정한다. 객체 데이터는 객체 그 자체로 저장되어야 한다. 메소드가 호출될 때 마다 객체에 액세스 할 수 있는 이유는 객체로의 레퍼런스는 그러한 메소드에 전달된 첫 번째 매개변수이기 때문이다.
DESTROY()
와 AUTOLOAD()
같은 특정 메소드가 있는데 이것은 특정 조건에서 펄에 의해 자동으로 호출된다. AUTOLOAD()
는 동적 메소드 이름을 허용하는데 사용되는 메소드이다. DESTROY()
는 객체 소멸자(destructor) 이지만, 정말로 필요한 경우가 아니라면 사용하지 말아야 한다. 펄에서 소멸자를 사용하는 것은 C/C++ 프로그래머로서 자신을 생각하고 있다는 의미가 된다.
상속에 대해 살펴보자. 펄에서 이것은 @ISA
변수를 변경하여 수행된다. 클래스 이름 리스트를 그 변수에 할당하면 된다. 그것으로 충분하다. @ISA
에 무엇이든 둘 수 있다. 클래스를 Satan
의 자식으로 만들 수 있다. 펄은 상관하지 않는다.
|
이것은 펄 OOP의 기본이다. 다른 많은 언어들도 연구해야 한다. 이를 주제로 다룬 책들도 많다. 참고자료 리스트도 꼼꼼히 살펴보기 바란다.
h2xs
펄 클래스를 작성하고 문서 (POD) 스켈레톤(skeleton)을 작성할 툴이 있다면 더욱 행복해질 것 같지 않은가? 펄에는 이러한 종류의 툴이 있다: h2xs
.
"-A -n Module
" 플래그는 중요하다. 기억하기 바란다. 이것을 이용하여, h2xs는 유용한 파일로 가득찬 "Module" 이라는 스켈레톤 디렉토리를 만든다:
Module.pm
, 이미 작성된 스켈레톤 문서를 가진 모듈.Module.xs
, 모듈을 C 코드로 연결하는데 사용.MANIFEST
, 패키지용 파일 리스트.test.pl
, 스크립트를 테스트하는 스켈레톤.Changes
, 모듈의 변경 기록.Makefile.PL
, makefile 생성자(generator).
이 모든 파일을 사용할 필요는 없지만 이와 같은 것이 존재하고 있다는 것을 알아두는 것이 낫다.
- 1장 (코드 가이드라인), 2장 (코드 주석), 3장 (루프 신택스), 4장 (함수 프로그래밍): 보다 나은 프로그래밍으로 가는 길 시리즈.
- Object Oriented Perl: Damian Conway (Manning Publications, 2000).
- Perldoc.com.
- comp.object Object FAQ.
- Programming Perl, Third Edition: Larry Wall, Tom Christiansen, Jon Orwant (O'Reilly & Associates, 2000).
- developerWorks "Cultured Perl" 시리즈:
- 프로그래머의 Linux 지향 설정
- Perl로 애플리케이션 구성
- Perl을 이용하여 UNIX 시스템 관리 자동화하기
- 쉬운 Perl 디버깅 (US)
- "JAPH"
- Perl의 유전자 알고리즘
- One-liners 개론
- C와 Java 프로그래머를 위한 Perl
- Perl로 Excel 파일 읽기/쓰기
- "Programming Perl" the 3rd Edition
- Perl의 데이터 저장 기술 (US)
필자소개 Teodor Zlatanov는 보스턴 대학에서 컴퓨터 공학을 전공했다. 졸업 후 Perl, Java, C, C++를 사용하여 프로그램을 개발하였다. |
'Computer_language > C++' 카테고리의 다른 글
C++ class에서 함수정의에 사용된 static [출처] C++ class에서 함수정의에 사용된 static|작성자 정천사 (0) | 2009.01.12 |
---|---|
Static Class 에 대한 정의 (0) | 2009.01.12 |
정적 중첩 클래스 (0) | 2009.01.12 |
각 상속 테스트 (0) | 2009.01.12 |
Ubuntu에서, c, c++관련 컴파일러 설치 [출처] Ubuntu에서, c, c++관련 컴파일러 설치|작성자 용이 (0) | 2009.01.12 |
분류 : OS : Alzza RedHat 5.2 ( Linux )
System 관리 - log
활용예 : 아파치 로그에 적용하기
최종 수정일 : 1999-12-02
쓸만한 웹로그 분석 프로그램을 찾다가 아주 좋은 정말 COOL한
프로그램을 찾았습니다.
이 프로그램의 장점은 분석 결과를 그래픽으로 처리해서
분석 결과을 한눈에 알수 있도 또,, 보여주는 파일 html 파일이
한글로도 출력이 된다는 것입니다.
여러가지 언어를 지원해서 정말 좋습니다.
그래도 단점은 있습니다.
로그 분석을 원할때마다 이 프로그램을 실행하여 주어야 한다는
것입니다. CGI 형태로는 될수 있는지 아직 확인 하지 않았습니다.
이 프로그램을 찾기 위해서 프레쉬미트를 수 없이 뒤적이다가
결국 많은 사람(6)이 추천한다는 글을 보고서 저도 설치을 해보니
정말 좋더군요..
이까지 하고 프로그램을 얻는 방법과 설치 방법에 대해서 이야기
하겠습니다.
먼저 1. 프로그램 구하기
http://www.mrunix.net/webalizer/
사이트에 가시면 최신의 소스와 바이너리를 구할수 있습니다.
여기에 보니깐.. 레드햇5.0 바이너리가 있더군요..
그렇지만 저는 소스들 받아다가 컴파일 하였습니다.
저는 소스를 받아서 컴파일 했기에 정말 한글 지원을 할수 있었
습니다. 그렇지만 바이너리는 한글을 지원하게 되었는지는 모르겠
습니다.
2. complie
./configure --prefix=/usr/local/webalizer --with-language=korean
make 하면 자 컴파일 끝..
3. install
위의 configure 에서 prefix=/usr/local/webalizer
이기에 이 디렉토리가 미리 존재 해야 합니다.
/usr/local/webalizer
/usr/local/webalizer/bin
/usr/local/webalizer/man
/usr/local/webalizer/man/man1
이렇게 디렉토리를 만들어 주고서
make install
을 합니다.
그러면.. 어느 파일이 어디로 카피되는지 알수 있습니다.
이 이후.. /etc/에 가 보시면
webalizer.conf.sample 이 있습니다.
이 파일을 webalizer.conf 로 복사해서 편집을 합니다.
LogFile /usr/local/apache/logs/access_log
LogType web
OutputDir /usr/local/apache/htdocs/usage
HostName Myhome.home
이 부분을 자신의 사이트로 고치시면 다른것 신경 쓰지 않고 바로 할수 있습니다.
여기서 OutputDir 이라는 디렉토리도 역시 미리 생성 되어 있어야
합니다.
그 이후
/usr/local/webalizer/bin/webalizer
를 실행시키면 usage 밑 디렉토리에 여러가지 파일이
생겨 있습니다.
브라우져로 보면 많은 정보들을 볼수 있습니다.
끝으로.. 정말 좋은 프로그램입니다.
필요 하신 분들은 보시기 바랍니다.
<덧붙이기.. >
필요할때마다 로그분석을 하여도 되지만..
cron을 이용해서 매일 분석 하게끔 하여 줄수 있습니다.
이 부분은 리눅스 초심자들이 궁금해 할까 적습니다.
/etc/cron.daily 디렉토리에 아래와 같은 파일을 생성 하면
webalizer 라는 파일을 생성 하시고
그 내용은
!/bin/sh
/usr/local/webalizer/bin/webalizer
을 생성하여주면 하루에 한번씩 로그 분석 결과를 볼수 있습
니다..
2006년 AJAX (비동기 Javascript and XML) 열풍이 불면서 MS에서는 Atlas라는 코드명으로 시작하여 현재는 ASP.NET AJAX 1.0 정식버전이 나왔지요. Atlas까지는 클래스 라이브러리로 제공을 하지만 ASP.NET AJAX 1.0 부터는 설치형을 제공해주고 있습니다.
하지만 .NET 호스팅을 사용하시는 분들은 많이 고민을 할듯 합니다. 자신의 사이트에 AJAX를 도입하고 싶은데 막상 웹호스팅 회사에서는 AJAX 컴포넌트를 제공해주지를 않는 경우이죠. 이를 극복하기 위해 고민을 하다가 방법을 알아냈습니다~(짝짝짝)
첫번째로 생각할 점은 아무리 Atlas에서 ASP.NET AJAX로 넘어왔다 하더라도 AJAX는 '클래스라이브러리 (.dll)'를 통해서 실행된다는 것이지요. 즉, 바이너리 파일을 담당하는 폴더인 /BIN 에 AJAX에 관련된 .dll 파일을 넣는다면 무리없이 실행된다는 것이지요.
그럼 웹호스팅에 AJAX를 꾸겨넣어(?) 봅시다~~
1. ASP.NET AJAX 공식 사이트(http://ajax.asp.net/)에서 AJAX 1.0을 다운받고 설치합니다.
AJAX에 관심있으신 분들이라면 이 사이트를 안가보신 분이 없겠지요 ^^ 동영상 강좌와 커뮤니티를 지원해주고 가장 최신 버전의 AJAX를 제공해줍니다. 이를 설치하는 이유는 AJAX에 관련된 .dll 파일을 얻기 위한 것입니다.
2. 필요한 .dll파일들을 복사하세요.
저는 C:\Program Files\Microsoft ASP.NET\ASP.NET 2.0 AJAX Extensions\v1.0.61025\ 에 있더군요. AJAX가 설치된 폴더에서 다음 .dll파일들을 따로 복사합니다.
AJAXExtensionsToolbox.dll
System.Web.Extensions.dll
System.Web.Extensions.Design.dll
각각의 클래스 라이브러리들이 어떠한 기능을 하는지 궁금하신 분은.. 저에게는 능력의 한계라~ ASP.NET AJAX Documentation을 확인해주시기 바랍니다.
3. 그리고 ASP.NET AJAX Control Tookit도 다운받고 압축을 푸세요.
(http://www.codeplex.com/AtlasControlToolkit/Release/ProjectReleases.aspx?ReleaseId=1425)
ASP.NET AJAX에서 기본으로 제공해주는 컨트롤을 사용하기 위해서 .dll 파일을(AjaxControlToolkit.dll) 가져와야 합니다. \SampleWebSite\Bin\ 여기에 컴파일된 클래스라이브러리가 있으니 이것도 복사를 해두세요.
4. 자~ AJAX를 도입할 웹사이트에 Bin폴더를 만들고 지금까지 모아놓은 4개의 .dll파일을 복사합니다.
5. 웹호스팅에 올립니다~~ 끝!
'Web > ajax' 카테고리의 다른 글
Ajax와 XML: 다섯 개의 추천할 만한 Ajax 위젯 (한글) (0) | 2009.01.12 |
---|---|
Ajax와 XML: 최고의 Ajax 배우기 (한글) (0) | 2009.01.12 |
php java ajax 웹프로그래밍 기술서 출처 (0) | 2009.01.12 |
[IBM 디벨로퍼웍스] Ajax로 SOAP 웹 서비스 호출하기, Part 1: 웹 서비스 클라이언트 구현하기 (한글) [출처] [IBM 디벨로퍼웍스] Ajax로 SOAP 웹 서비스 호출하기, Part 1: 웹 서비스 클라이언트 구현하기 (한글) (0) | 2009.01.12 |
난이도 : 초급
Jack D Herrington, Senior Software Engineer, Leverage Software Inc.
2007 년 6 월 05 일
[출처] Ajax와 XML: 최고의 Ajax 배우기 (한글)|작성자 마검린
Web 2.0에서 최상의 Asynchronous JavaScript™ + XML (Ajax) 애플리케이션을 사용해봅시다. 이러한 애플리케이션들이 사용자 레벨에서 어떻게 성공을 거둘 수 있는지, 자신의 Web 2.0 애플리케이션에 맞는 기술을 찾아 뛰어난 사용자 경험을 이룩하는 방법은 무엇인지를 모색해봅시다.
본 기술자료에서는 최신 웹 애플리케이션들에게서 배울 점을 찾아볼 것이다. 모방의 대상이 되는 사이트들은 이를 문제 삼지는 않을 것이다. 결국 모방은 칭찬의 또 다른 표현이기도 하다.
필자는 기술적인 측면에만 주 초점을 맞추지는 않을 것이다. 이러한 사이트들의 기술적인 측면, 즉 Ajax를 통해 데이터가 전달되는 방법이 중요하긴 하지만 이것이 성공적인 사이트를 만드는 것은 아니기 때문이다. 이러한 사이트들이 브라우저의 Ajax 기능들과 Dynamic HTML (DHTML)을 함께 사용하여 매력적인 사용자 경험을 어떻게 만들어 내는지를 생각해 봐야 한다. 또한, 이러한 사이트들이 사용자 커뮤니티와 어떻게 상호 작동 할 수 있는지도 봐야 한다. 이러한 모든 요소들이 성공적인 사이트를 만드는데 있어서 기술만큼 중요한 것이다.
"가장 영향력 있는 Web 2.0 애플리케이션"에 대한 오스카 또는 골든 글로브 시상식이 있다면, 상은 Google Maps에 돌아가야 한다. 필자의 동료들이 Google Maps를 처음 봤을 때 그들의 반응이 뚜렷하게 기억난다. 브라우저에서 어떻게 이러한 것들이 가능할까? Google Maps는 브라우저의 애플리케이션에 사용자가 기대하는 바를 재정립함으로써 Web 2.0 혁신을 주도했다고 본다.
이 글을 읽고 있는 독자들도 Google Maps를 사용해 보았는지는 모르겠지만, 어쨌든 그림 1의 사이트를 보도록 하자.
그림 1. 현재의 Google Maps 버전

마치 종이로 된 지도를 보는 것처럼 쉽게 지도를 클릭하고 드래그 할 수 있다. 여러분이 방향을 잡으면 디스플레이 명멸(blinking)이나 지도를 이동시키지 않고도 지도 상에 라인으로서 나타난다. 사실, 대부분의 Google Maps의 기능은 서버의 HTML 페이지 없이도 실행된다.
Google Maps 다음으로 Ajax and Dynamic HTML이라는 단어가 두 번째 웹 혁명을 일으켰다. 이상한 점은 더 정확히 말해서 (XMLHTTP
객체를 사용하여 요청을 송수신 하는 것으로 Ajax를 정의한다면), Google Maps는 Ajax를 사용하지 않는다. Google Maps는 동적으로 생성된 <script>
태그를 사용하여 데이터를 이동한다. 이것은 XMLHTTP
객체 보다 앞서는 기술이다.
그런데 왜 Google Maps는 Ajax를 사용하지 않는 것인가? Google 엔지니어들의 생각까지는 알 수 없지만, 필자의 생각으로는 Google Maps는 "get-go"가 아닌 JavaScript "mashup-able"이 되도록 설계되었기 때문이다.
이 글 초반에서, 필자는 사용자 커뮤니티를 지원하는 것에 대해 이야기 했다. 이것은 중요하다고 생각한다. 매시업은 사용자 커뮤니티를 지원하기에 딱 알맞다. 매시업은 한 사이트에서 기능과 또 다른 사이트의 기능을 결합하여 보다 더 흥미로운 것으로 만드는 것이다. 매시업의 좋은 예는 Craigslist에서 렌탈 리스팅을 가져와서, Google Maps를 사용하여 이들을 지도 위에 배치하는 것이다.
Google Maps 매시업의 또 다른 예제는 MapMyRun.com이다. 이것은 Google Maps를 사용하여 달리기 선수들이 지도 상에서 거리를 파악할 수 있도록 한다. (그림 2)
그림 2. Map My Run 인터페이스

여기에서 필자는 왼쪽 페인에 있는 인풋 필드에 시작 위치를 넣는다. 그런 다음 마우스를 사용하여 달리기 코스를 가리킨다. 필자가 클릭하면 왼쪽 페인은 동적으로 업데이트 되어 거리를 보여준다. 줌인 기능을 통해 보다 상세하게 보거나 길을 벗어날 경우 위성 모드로 변환한다.
모든 어려운 지도 작업은 Google Maps에 의해 수행된다. MapMyRun 사이트는 지도 위에 몇 개의 JavaScript 코드를 배치하여 마우스 클릭을 처리하고 거리를 계산한다.
그렇다면 성공적인 Web 2.0 애플리케이션을 구현할 때 Google Maps에서 무엇을 배웠을까?
- 브라우저를 사용한다: Google Maps는 현대적인 브라우저의 동적인 측면을 매우 잘 활용한다. 이러한 브라우저 기능들을 사용하여 매력적인 사용자 경험을 만들어 낸다.
- Ajax 순수성은 중요하지 않다: 극소수의 사람들은 Google Maps가 순수한 Ajax 애플맄이션이 아니라는 것을 알고 있다. 그러나 이러한 사람들 조차 그것을 문제 삼지 않는다. Google Maps는 사용자에게 놀라운 기능을 제공한다.
XMLHttp
이 사용되지 않는다는 것은 문제가 되지 않는다. 특정 기술에 너무 얽매일 필요가 없다. - JavaScript 매시업: JavaScript 코딩을 사용하여 하나의 사이트에서 또 다른 사이트로 기능을 삽입하는 기능은 매우 매력적이다. 특정 기능에 대한 중요한 소스를 사용할 수 있는 강점을 갖고 있다.
![]() |
![]()
|
이제 직접 경험해 보자. Google Maps는 Web 2.0 애플리케이션에 매우 높은 장벽을 치고 있다. 하지만 Ajax를 사용하여 애플리케이션에 엄청난 가치를 빠르게 추가할 수 있다. 그러한 가치의 예가 TaDaList이다. TaDaList는 매우 단순한 (그리고 무료의) to-do 리스트 매니저이다. 사이트를 설명하기 위해, 수영 연습을 위해 필자가 해야 할 일을 상기시켜 주는 계정과 수영 리스트를 그림 3과 같이 만들었다.
그림 3. 수영 리스트

고글을 구매해야 한다는 것을 추가해야 하므로 그 내용을 텍스트 필드에 입력하고 Add to list를 클릭한다. 이 아이템은 페이지 리프레시 없이 곧 알맞은 리스트에 추가된다. (그림 4)
그림 4. "Buy New Goggles"를 추가한 후

많은 것들이 있는 것 같지는 않고 Ajax를 사용하여 구현하기도 어렵지 않은데도 데스크탑 애플리케이션에서나 기대할 수 있었던 세련된 감각을 느낄 수 있다.
TaDaList는 Rails 프레임웍에서 작성된다는 것을 명심하라. 사실, 이것은 Rails를 배우는 사람들이 사용하는 데모용 애플리케이션이다. Rails 프레임웍에서는 이러한 유형의 Ajax 작업을 매우 빠르게 할 수 있다.
필자는 Rails에서 2분여 만에 매우 기본적인 TaDaList를 작성했다. to-do 아이템의 리스트는 그림 5에 나타나 있다.
그림 5. to-do 아이템 리스트

그리고 나서 Buy earplugs
를 입력하고 Add를 클릭한다. 페이지를 리프레시 하지 않고도 아이템이 리스트에 나타난다. (그림 6)
그림 6. "Buy earplugs"를 추가한 후

그 다음에는 to-do 아이템들을 저장할 작은 데이터베이스를 만들었다. 그리고 나서 Listing 1에 보이는 Rails 컨트롤러를 만들었다.
Listing 1. Todo_controller.rb
|
Listing 1의 코드는 두 개의 메소드를 사용한다. list()
메소드는 페이지를 보여준다. add()
메소드는 새로운 아이템을 리스트에 추가하고 그 리스트를 HTML로 리턴한다.
list()
메소드용 RHTML은 Listing 2에 나타나 있다.
Listing 2. List.rhtml
|
이 페이지는 form_remote_tag
를 사용하여 단순한 형태의 콘텐트를 컨트롤러에 있는 add()
메소드에 제출한다. add()
메소드는 to-do 아이템을 테이블에 추가하고 결과 <div>
태그에 새로운 콘텐트를 리턴한다. 이 코드는 Listing 3과 같다.
Listing 3. Add.rhtml
|
그렇다면 TaDaList에서 필자는 무엇을 배웠을까? 우선, 웹 애플리케이션을 위한 더 나은 데스크탑 느낌을 갖기 위해서는 Ajax가 갈 길이 멀다는 점이다. 두 번째로, Ajax를 채택하고 있는 웹 프레임웍의 선택은 이러한 유형의 작업을 수월하게 한다는 점이다.
![]() |
![]()
|
Campfire는 같은 그룹(37signals)에서 개발한 TaDaList와 비슷한 사이트이다. 이 경우, 애플리케이션은 온라인 채팅을 호스팅 하고 파일 전송을 쉽게 함으로써 원격 팀을 위한 가상의 친목회를 시뮬레이트 하기 위해 개발되었다.
필자는 시험 계정을 설정하고 몇 가지 이미지 업로딩과 함께 채팅을 수행했다. 결과는 그림 7과 같다.
그림 7. 원격 팀들을 위한 가상 친목회

디스플레이의 왼편을 보면 누구나 언제라도 새로운 메시지를 게시할 수 있는 간단한 채팅 창이 있다. 오른편에는 누가 온라인 상태에 있는지, 파일 업로딩 장소는 어디에 있는지를 나타낸다.
파일 업로딩은 그 자리에서 JavaScript 코드를 사용하여 수행되어 파일 업로드 프로세스를 감시한다. 다시 말해서, 대화 시 다른 페이지로 이동할 필요 없이 파일과 이미지를 추가할 수 있다.
Campfire 역시 몇 가지 교훈을 준다. 우선, 사용자들이 데스크탑 애플리케이션에서 기대하는 채팅 서비스를 대체할 대담성을 갖고 있다. 하지만, 그룹 미팅의 정황에서 채팅을 호스팅 함으로써 이를 무난히 수행하고, 데스크탑과 비교해 볼 때 기능면에서 제한이 있는 시스템을 구현하지만 미팅의 정황에서만 사용할 수 있기 때문에 더욱 값지다.
두 번째 교훈은 파일 업로딩 같은 페이지 리프레시를 해야 하는 작동이 처리되어 어떤 페이지 로딩도 필요 없다. 따라서 사용자는 자신의 태스크에 집중할 수 있고 데스크탑 애플리케이션 느낌을 강화할 수 있다.
![]() |
![]()
|
이러한 사이트들의 일부가 Web 2.0을 사용한다면, YourMinis는 또 다른 영역에서, 여러분의 웹의 widget/gadget 사이트가 된다. 이를 사용하여 여러분은 다양한 위젯(또는, Microsoft lingo를 선호할 경우 gadgets,)을 호스팅 하는 페이지를 생성 및 커스터마이징 할 수 있다. 페이지는 대시보드로서 작동하면서 매력적인 방식으로 정보를 제때에 제공한다.
그림 8은 페이지에 Rottentomatoes 영화 위젯을 배치한 후의 사이트 모습니다.
그림 8. 영화 리뷰를 보여주는 YourMinis

Rottentomatoes는 영화 리뷰 사이트인데 약간의 트위스트가 있다. 수 백 개의 영화 리뷰들에서 점수를 모아서 그 수를 백분율로 제공한다. 60% 이상 점수를 가진 영화는 fresh(좋은 영화)로 간주된다. 이 경우, 필자는 Bridge To Terebithia,를 선택했고 우편 번호만 제공하면 위젯을 통해 영화 시간을 알 수 있다. (그림 9)
그림 9. 영화 시간을 보여주는 영화 위젯

인터페이스는 깔끔하고 빠르며 대중적인 브라우저에서도 잘 작동한다. 위젯 역시 다양한 장소(예를 들어, 이 사이트의 생성자의 블로그)에서 호스팅 할 수도 있다.
이 사이트 외에도, YourMinis는 Firefox 확장도 있기 때문에 여러분이 검색하고 있을 때 여러분을 지켜본다. RSS 피드나 MP3 같은 YourMinis와 함께 사용할 것을 찾으면 리소스를 사용할 수 있다는 것을 알려준다. 비교적 쉬운 브라우저와의 통합은 사이트를 사용자 데스크탑과 더욱 밀접히 통합할 수 있는 좋은 방법이다.
YourMinis는 Web 2.0에 대해서 더 많은 교훈을 준다. 우선, minis와 프레임웍은 Macromedia Flash로 구현된다. 사용자의 관점에서 보면, 이는 문제가 아니다. 특정 기술의 선택 문제는 궁극적인 사용자 이익보다는 중요하지 않다.
개발자들이 페이지 디자인을 커뮤니티에 기여하게끔 만든다. 사용자 커뮤니티와 함께 한다는 것은 여러분이 원래 상상하지도 못했던 방향으로 사이트를 만들 수 있다는 것을 시사한다.
특별한 사이트는 아니지만, Lightbox 기술은 최신 사이트에서 중요한 역할을 한다. lightbox는 사용자 인터페이스 기술과 Ajax를 결합한 것이다. 웹 페이지 예제를 보자. (그림 10)
그림 10. Lightbox JS의 홈페이지

이미지를 클릭하면 전체 페이지가 어두워지고 선택한 박스의 줌인 이미지가 페이지 중앙에 나타난다. (그림 11)
그림 11. 이미지 클릭 후에 나타나는 Lightbox

이 기술은 많은 장점이 있다. 사용자의 관심을 페이지의 나머지 부분들에서 끌어내어 선택한 부분에 집중할 수 있도록 한다. 사용자는 Close를 클릭하고 정상 페이지로 돌아갈 수 있기 때문에 사용자들이 페이지를 많이 이동하지 않고도 상세한 부분들을 볼 수 있다.
Lightbox 기술은 이미지나 비디오에 좋을 뿐만 아니라, 텍스트 콘텐트에도 유용하다. 필자가 자주 방문하는 콘텐트 사이트는 Lightbox 기술을 사용하여 홈 페이지에 있는 각 아티클의 시놉시스를 제공한다. 하지만 이 시놉시스는 사용자가 (Ajax를 통해) Lightbox 링크를 클릭할 경우에만 로딩된다. 따라서 사용자는 한 페이지에서 여러 아티클 시놉시스 아이템을 읽을 수 있고 서버 대역폭을 줄일 수 있다.
Lightbox를 만드는데 여러 오픈 소스 JavaScript 라이브러리들을 사용할 수 있다. 위에 설명한 것은 Lightbox JS version 2이다.
![]() |
![]()
|
이 글을 쓰면서 필자는 많은 Web 2.0 사이트들을 둘러보았다. 대부분이 위에 설명한 예제들에는 미치지 못했다. 특히 Google은 여러 가지 뛰어난 오퍼링을 갖고 있다. Google Documents와 Spreadsheets는 브라우저 내에서 WYSIWYG 에디팅이 어디까지 갈 수 있는지를 증명하고 있다. Google Reader는 RSS 피드를 통해 호스팅 솔루션을 제공하여 사용자가 어떤 장소에서든 뉴스를 볼 수 있게 하는 방법을 시사하고 있다. Google Mail은 Ajax, JavaScript, DHTML, Google Maps를 사용한다.
Google이 탁월성을 보이는 또 다른 분야는 모바일 접근성이다. Google의 모든 서비스들은 전화기와 기타 작은 장치에서도 잘 작동하는 버전을 갖고 있다. 하나의 Google 계정으로 웹 버전과 전화기 버전에 맞춰 커스터마이징 된 홈페이지가 생긴다.
놀라운 Ajax 작동을 보이는 것이 Google 만은 아니다. Meebo는 단순하지만 우아한 인터페이스를 가진 채팅 애플리케이션의 좋은 예이다. Kiko는 캘린더 편집에 DHTML을, 새로운 약속, 연락처, 관련 정보들로 서버를 업데이트할 때는 Ajax를 사용하는 캘린더 애플리케이션이다.
![]() |
![]()
|
이 글에서 설명한 모든 사이트들에서 배울 점은 아주 많다. 특히, 훌륭한 기술 트릭을 배울 수 있다. 이 모든 사이트들이 공유하는 한 가지 공통적인 엘리먼트는 HTML과 JavaScript 코드의 결합에서 나오는 힘에 대한 깊은 신뢰이다. JavaScript 코드는 최근 프로그래밍 세계에서 나쁜 평판을 받았다. 필자가 들었던 대부분의 결점들은 JavaScript 언어 자체 보다는 Document Object Model (DOM)과의 브라우저 호환성과 더욱 관련이 있기 때문에 그러한 평판은 부당하다. 확실한 점은, 여러분이 매력적인 Web 2.0 애플리케이션을 만들고 싶다면 JavaScript 코드를 사용해야 한다는 것이다.
![]() |
초반에 언급했듯이, 기술만이 문제가 아니다. 매력적인 사용자 경험을 이룩하는 것에 관한 것이기도 하다. 필자가 이 글에서 설명하기 위해 선택했던 모든 사이트들은 이 분야에 새로운 지평을 연 것들이다. 일부는 단순한 폼에 복잡성을 숨기기도 했고(Google Maps), 어떤 것들은 Ajax를 통해 인터페이스를 향상시켰다.
Web 2.0 애플리케이션들 역시 커뮤니티가 있다. Google Maps에서는 사용자들이 자신들의 애플리케이션에 사용할 기술을 혼합할 수 있다. Campfire 같은 사이트들은 집중된 사용자 경험을 향상시킨다.
확실히, 여러분은 많은 것을 배울 수 있다. 하지만 감사하게도, JavaScript와 DHTML 애플리케이션을 쉽게 구현할 수 있기 때문에 Web 2.0 애플리케이션 구현이 더욱 즐거워 질 것이다.
[출처] Ajax와 XML: 최고의 Ajax 배우기 (한글)|작성자 마검린
'Web > ajax' 카테고리의 다른 글
Ajax와 XML: 다섯 개의 추천할 만한 Ajax 위젯 (한글) (0) | 2009.01.12 |
---|---|
ASP.NET AJAX를 지원하지 않는 웹호스팅에 AJAX 사용하기 닷넷 (0) | 2009.01.12 |
php java ajax 웹프로그래밍 기술서 출처 (0) | 2009.01.12 |
[IBM 디벨로퍼웍스] Ajax로 SOAP 웹 서비스 호출하기, Part 1: 웹 서비스 클라이언트 구현하기 (한글) [출처] [IBM 디벨로퍼웍스] Ajax로 SOAP 웹 서비스 호출하기, Part 1: 웹 서비스 클라이언트 구현하기 (한글) (0) | 2009.01.12 |
![]() |
|
'Web > ajax' 카테고리의 다른 글
Ajax와 XML: 다섯 개의 추천할 만한 Ajax 위젯 (한글) (0) | 2009.01.12 |
---|---|
ASP.NET AJAX를 지원하지 않는 웹호스팅에 AJAX 사용하기 닷넷 (0) | 2009.01.12 |
Ajax와 XML: 최고의 Ajax 배우기 (한글) (0) | 2009.01.12 |
[IBM 디벨로퍼웍스] Ajax로 SOAP 웹 서비스 호출하기, Part 1: 웹 서비스 클라이언트 구현하기 (한글) [출처] [IBM 디벨로퍼웍스] Ajax로 SOAP 웹 서비스 호출하기, Part 1: 웹 서비스 클라이언트 구현하기 (한글) (0) | 2009.01.12 |
[IBM 디벨로퍼웍스] Ajax로 SOAP 웹 서비스 호출하기, Part 1: 웹 서비스 클라이언트 구현하기 (한글) [출처] [IBM 디벨로퍼웍스] Ajax로 SOAP 웹 서비스 호출하기, Part 1: 웹 서비스 클라이언트 구현하기 (한글)
| Web/ajax 2009. 1. 12. 02:02난이도 : 중급
James Snell, Software Engineer, IBM
2007 년 8 월 14 일
Asynchronous JavaScript and XML (Ajax) 디자인 패턴을 사용하여 웹 브라우저 기반 SOAP 웹 서비스 클라이언트 구현하기.
Asynchronous JavaScript and XML (Ajax) 디자인 패턴에 기반하여 크로스 플랫폼, JavaScript 기반 SOAP 웹 서비스 클라이언트를 구현하는 방법을 다룬 시리즈의 첫 번째 기술자료입니다.
GMail, Google Maps, Flickr, Odeo.com 같은 유명한 웹 애플리케이션 서비스에서 사용된다는 이유로 유명해진 Ajax는 웹 개발자에게 비동기식 XML 메시징을 사용함으로써 그들의 웹 애플리케이션의 가치와 기능을 늘릴 수 있는 방식을 제공하고 있다. 이 글에서 소개하는 Web Services JavaScript Library는 SOAP 기반 웹 서비스를 호출하는데 지원을 추가함으로써 Ajax 패턴에 힘을 실어주는 기본 메커니즘을 확장한 것이다.
웹 브라우저 내에서 SOAP 웹 서비스를 호출하는 것은 복잡한 일이 될 수 있다. 대부분의 웹 브라우저가 각각 XML의 생성과 프로세싱을 약간 다른 방식으로 처리할 경우 특히 그렇다. 모든 브라우저들이 일관성 있게 구현하는 표준 API나 XML 프로세싱 기능들은 매우 적다.
브라우저 구현에서 일치하는 메커니즘 중 하나가 XMLHttpRequest API인데, 이것은 Ajax 디자인 패턴의 심장이다. Philip McCarthy가 developerWorks에 기고한 최신 글에서도, XMLHttpRequest는 비동기식 HTTP 요청들을 수행하는데 사용할 수 있는 JavaScript 객체이다. 이 글에서는 XMLHttpRequest 객체가 Ajax 디자인(참고자료)을 실행하는 방법을 이해하는데 도움이 되는 시퀀스 다이어그램(그림 1) 도 소개한다.
그림 1. Philip McCarthy의 Ajax Roundtrip 시퀀스 다이어그램

이 다이어그램에서, XMLHttpRequest 객체가 어떻게 작동하는지 정확히 볼 수 있다. 웹 브라우저 내에서 실행되는 일부 JavaScript 조각들은 XMLHttpRequest 인스턴스와 비동기식 호출로서 작동하는 함수를 만들어 낸다. 스크립트는 XMLHttpRequest 객체를 사용하여 서버에 대해 HTTP 연산을 수행한다. 응답을 받으면, 콜백 함수가 호출된다. 콜백 함수 내에서, 리턴된 데이터가 처리될 수 있다. 데이터가 XML이라면, XMLHttpRequest 객체는 브라우저의 XML 프로세싱 방식을 사용하여 그 데이터를 자동으로 파싱한다.
안타깝게도, XMLHttpRequest 객체는 Ajax 방식이 실행되는데 어려움을 겪는 곳에서 XML을 자동으로 파싱한다. 예를 들어, 필자가 요청하는 데이터가 다른 많은 XML Namespaces에서 온 엘리먼트를 포함하고 있는 SOAP Envelope이고, 필자는 yetAnotherElement
에서 attr
애트리뷰트의 값을 얻어야 하는 경우를 생각해 보자. (Listing 1.)
Listing 1. 다중 네임스페이스를 가진 SOAP Envelope
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <s:Header/> <s:Body> <m:someElement xmlns:m="http://example"> <n:someOtherElement xmlns:n="http://example" xmlns:m="urn:example"> <m:yetAnotherElement n:attr="abc" xmlns:n="urn:foo"/> </n:someOtherElement> </m:someElement> </s:Body></s:Envelope> |
Mozilla와 Firefox 브라우저에서, attr
애트리뷰트의 값을 추출하는 것은 간단하다. (Listing 2)
Listing 2. Mozilla와 Firefox에서 attr 애트리뷰트를 가져오는 메소드는 Internet Explorer에서는 작동하지 않는다.
var m = el.getElementsByTagNameNS( 'urn:example', 'yetAnotherElement')[0]. getAttributeNS( 'urn:foo', 'attr');alert(m); // displays 'abc' |
![]() |
|
안타깝게도, 이 코드는 Internet Explorer Version 6에서는 작동하지 않는다. 이 브라우저는 getElementsByTagNameNS 함수를 구현하지 않고, 사실 다소 도움이 안되는 방식인 XML 네임스페이스 접두사가 엘리먼트와 애트리뷰트 이름의 일부인 것처럼 취급하는 방식을 취하기 때문이다.
Internet Explorer의 XML 네임스페이스 지원 부족으로 SOAP 같이 네임스페이스 중심의 XML 포맷을 브라우저와 독립된 방식으로 처리하기가 더욱 어렵다. 결과에서 애트리뷰트의 값을 얻는 것 같은 간단한 일을 수행하기 위해서, 여러분은 기대한 작동이 여러 브라우저에서도 일관되도록 특별한 케이스 코드를 작성해야 한다. 다행히도, 이러한 특수 케이스 코드는 캡슐화 및 재사용 될 수 있다.
웹 브라우저 내에서 웹 서비스를 호출하고 SOAP 메시지들을 신뢰성 있게 처리하려면, 보안 문제를 이해해야 한다. ("보안" 참조) 또한, 기반 브라우저 XML 구현들의 불일치를 제거할 수 있는 JavaScript 스크립트 라이브러리를 작성하고(그림 2), 웹 서비스 데이터와 직접 작동할 수 있어야 한다.
그림 2. Web Services JavaScript Library를 사용하여 웹 브라우저 내에서 JavaScript로부터 웹 서비스 호출하기

그림 2의 Web Services JavaScript Library (ws.js)는 JavaScript 객체들과 유틸리티 함수들의 컬렉션으로서, SOAP 1.1 기반 웹 서비스를 지원한다. ws.js는 다음 객체들을 정의한다.
- WS.Call: XMLHttpRequest를 래핑하는 웹 서비스 클라이언트
- WS.QName: XML 수식명 구현
- WS.Binder: 커스텀 XML 직렬화/비직렬화 베이스
- WS.Handler: 요청/응답 핸들러 베이스
- SOAP.Element: XML DOM을 래핑하는 기본 SOAP 엘리먼트
- SOAP.Envelope: SOAP.Element를 확장하는 SOAP Envelope 객체
- SOAP.Header: SOAP.Element를 확장하는 SOAP 헤더 객체
- SOAP.Body: SOAP.Element를 확장하는 SOAP 바디 객체
- XML: XML을 핸들링 하는 크로스 플랫폼 유틸리티 메소드
ws.js의 핵심에는 웹 서비스를 호출하는 메소드를 제공하는 WS.Call 객체가 있다. WS.Call은 기본적으로 XMLHttpRequest 객체와의 인터랙션과 SOAP 응답 프로세싱을 담당하고 있다.
WS.Call 객체는 다음과 같이 세 개의 메소드를 노출한다.
- add_handler. Request/Response 핸들러를 프로세싱 체인에 추가한다. Handler 객체들은 웹 서비스 호출 전후에 호출되어 확장성 있는 사전 사후 호출 프로세싱을 발생시킨다.
- invoke. 지정된 SOAP.Envelope 객체를 웹 서비스로 보내고 응답을 받으면 콜백을 호출한다. 리터럴 XML 인코딩을 사용하는 문서 스타일의 웹 서비스를 호출할 때 이 메소드를 사용한다.
- invoke_rpc. RPC-Style 요청을 캡슐화 하여 SOAP.Envelope을 만들고 이것을 웹 서비스로 보내면서, 응답을 받을 때 콜백을 호출한다.
WS.Call 객체는 일반적으로 XMLHttpRequest 객체의 맨 위에 있는 씬(thin) 래퍼일 뿐이지만, 여러분의 삶을 편하게 해주는 많은 액션을 수행한다. 이 액션에는 SOAP 1.1 스팩에서 필요로 하는 SOAPAction HTTP 헤더를 설정하는 것이 포함된다.
![]() |
![]()
|
Web services JavaScript Library에서 제공된 API는 다소 단순하다.
SOAP.* 객체들 (SOAP.Element
, SOAP.Envelope
, SOAP.Header
, SOAP.Body
)은 SOAP Envelopes를 구현하고 읽는 방식을 제공하여(Listing 3), XML 문서 객체 모델을 실행하는 상세를 없앤다.
Listing 3. SOAP Envelope 구현하기
var envelope = new SOAP.Envelope();var body = envelope.create_body();var el = body.create_child(new WS.QName('method','urn:foo'));el.create_child(new WS.QName('param','urn:foo')).set_value('bar'); |
Listing 4는 Listing 3의 코드에서 만들어진 SOAP Envelope이다.
Listing 4. SOAP Envelope 구현하기
<Envelope xmlns="http://schemas.xmlsoap.org"> <Body> <method xmlns="urn:foo"> <param>bar</param> </method> </Body></Envelope> |
여러분이 만들고 있는 SOAP Envelope가 RPC-Style 요청을 대표하는 것이라면, SOAP.Body 엘리먼트는 set_rpc
메소드(Listing 5)를 제공한다. 이것은 연산 이름, 인풋 매개변수의 어레이, SOAP 인코딩 스타일 URI에 주어진 요청의 전체 바디를 구현한다.
Listing 5. RPC-Request Envelope 구현하기
var envelope = new SOAP.Envelope();var body = envelope.create_body();body.set_rpc( new WS.QName('param','urn:foo'), new Array( {name:'param',value:'bar'} ), SOAP.NOENCODING); |
각각의 매개변수는 다음과 같은 프로퍼티를 가진 JavaScript 객체 구조로서 전달된다.
- name. 매개변수의 이름을 지정하는 스트링 또는 WS.QName 객체. 필수.
- value. 매개변수의 값. 값이 단순한 데이터 유형(스트링 또는 정수)이 아니라면, WS.Binder가 지정된다. 이것은 해당 XML 구조로 값을 직렬화 할 수 있다.필수.
- xsitype: 매개변수의 XML Schema Instance Type을 구분하는 WS.QName (예를 들어,
xsi:type="int"
라면,xsitype:new WS.QName('int','http://www.w3.org/2000/10/XMLSchema')
이다.) 선택. - encodingstyle.: 이 매개변수에 의해 사용되는 SOAP Encoding Style을 구분하는 URI. 선택.
- binder: 매개변수를 XML로 직렬화 할 수 있는 WS.Binder 구현. 선택
예를 들어, "abc"라는 이름을 가진 매개변수를 XML Namespace "urn:foo", "int"의 xsi:type, "3" 으로 지정하려면, 다음 코드를 사용한다: new Array({name:new WS.QName('abc','urn:foo'), value:3, xsitype:new WS.QName('int','http://www.w3.org/2000/10/XMLSchema')})
.
서비스 요청을 위해 SOAP.Envelope을 구현하면, 그 SOAP.Envelope을 WS.Call 객체 invoke
메소드로 보내서 Envelope 내부에 인코딩 된 메소드를 호출한다: (new WS.Call(service_uri)).invoke(envelope, callback)
SOAP.Envelope을 직접 구현하는 것에 대한 대안으로서, WS.QName, 매개변수 어레이, 인코딩 스타일을 WS.Call 객체의 invoke_rpc
메소드로 전달할 수 있다. (Listing 6)
Listing 6. WS.Call 객체를 사용하여 웹 서비스 호출하기
var call = new WS.Call(serviceURI); var nsuri = 'urn:foo';var qn_op = new WS.QName('method',nsuri);var qn_op_resp = new WS.QName('methodResponse',nsuri); call.invoke_rpc( qn_op, new Array( {name:'param',value:'bar'} ),SOAP.NOENCODING, function(call,envelope) { // envelope is the response SOAP.Envelope // the XML Text of the response is in arguments[2] } ); |
invoke
메소드 또는 invoke_rpc
메소드를 호출할 때, WS.Call 객체는 기반 XMLHttpRequest 객체를 만들고, SOAP Envelope를 포함하고 있는 XML 엘리먼트로 전달하고, 응답을 받아 파싱하며, 콜백 함수를 호출한다.
SOAP 메시지의 사전 및 사후 처리를 확장하기 위해, WS.Call 객체는 WS.Handler 객체의 컬렉션을 등록할 수 있다. (Listing 7) 이들은 호출 사이클 동안 모든 요청, 응답, 에러 시 호출된다. 새로운 핸들러가 WS.Handler JavaScript 객체를 확장함으로써 구현될 수 있다.
Listing 7. 요청/응답 핸들러 생성 및 등록하기
var MyHandler = Class.create();MyHandler.prototype = (new WS.Handler()).extend({ on_request : function(envelope) { // pre-request processing }, on_response : function(call,envelope) { // post-response, pre-callback processing }, on_error : function(call,envelope) { }});var call = new WS.Call(...);call.add_handler(new MyHandler()); |
핸들러들은 전달되는 SOAP Envelope에서 정보를 삽입 또는 추출하는 태스크에 가장 유용하다. 예를 들어, 적절한 Web Services Addressing 엘리먼트를 SOAP Envelope 헤더로 자동 삽입하는 것을 생각해 볼 수 있다. (Listing 8)
Listing 8. WS-Addressing Action 헤더를 요청에 추가하는 샘플 핸들러
var WSAddressingHandler = Class.create();WSAddressingHandler.prototype = (new WS.Handler()).extend({ on_request : function(call,envelope) { envelope.create_header().create_child( new WS.QName('Action','http://ws-addressing','wsa') ).set_value('http://www.example.com'); }}); |
WS.Binder 객체(Listing 9)는 SOAP.Element 객체의 커스텀 직렬화/비직렬화를 수행한다. WS.Binder 구현은 다음과 같은 두 개의 메소드를 제공해야 한다.
- to_soap_element. JavaScript 객체를 SOAP.Element로 직렬화 한다. 전달되는 첫 번째 매개변수는 직렬화 되는 값이다. 두 번째 매개변수 값은 SOAP.Element로 직렬화 되어야 한다. 이 메소드는 어떤 값도 리턴하지 않는다.
- to_value_object. SOAP.Element를 JavaScript 객체로 비직렬화 한다. 메소드는 비직렬화 된 값 객체를 리턴해야 한다.
Listing 9. WS.Binding 구현 샘플
var MyBinding = Class.create();MyBinding.prototype = (new WS.Binding()).extend({ to_soap_element : function(value,element) { ... }, to_value_object : function(element) { ... }}); |
![]() |
![]()
|
Web Services JavaScript Library의 기본 기능을 설명하는 샘플 객체를 설명했다. 이 데모에서 사용되는 웹 서비스(Listing 10)은 WebSphere Application Server에서 구현되고 간단한 Hello World 함수를 제공한다.
Listing 10. 간단한 자바 기반 Hello World 웹 서비스
package example;public class HelloWorld { public String sayHello(String name) { return "Hello " + name; }} |
서비스를 WebSphere Application Server로 구현 및 전개한 후에, 서비스의 WSDL 디스크립션(Listing 11)은 Hello World 서비스를 호출하기 위해 전달해야 하는 SOAP 메시지를 정의한다.
Listing 11. HelloWorld.wsdl의 코드
<wsdl:portType name="HelloWorld"> <wsdl:operation name="sayHello"> <wsdl:input message="impl:sayHelloRequest" name="sayHelloRequest"/> <wsdl:output message="impl:sayHelloResponse" name="sayHelloResponse"/> </wsdl:operation></wsdl:portType> |
Web Services JavaScript Library를 사용하여, Hello World 서비스를 호출하는 메소드를 구현할 수 있다. (Listing 12)
Listing 12. WS.Call을 사용하여 Hello World 서비스 호출하기
<html><head>...<script type="text/javascript" src="scripts/prototype.js"></script><script type="text/javascript" src="scripts/ws.js"></script><script type="text/javascript">function sayHello(name, container) { var call = new WS.Call('/AjaxWS/services/HelloWorld'); var nsuri = 'http://example'; var qn_op = new WS.QName('sayHello',nsuri); var qn_op_resp = new WS.QName('sayHelloResponse',nsuri); call.invoke_rpc( qn_op, new Array( {name:'name',value:name} ),null, function(call,envelope) { var ret = envelope.get_body().get_all_children()[0]. get_all_children()[0].get_value(); container.innerHTML = ret; $('soap').innerHTML = arguments[2].escapeHTML(); } );}</script></head>... |
웹 애플리케이션 어디에서나 sayHello
함수를 호출함으로써 Hello World 서비스를 호출할 수 있다. (Listing 13)
Listing 13. sayHello 함수 호출하기
<body><input name="name" id="name" /><input value="Invoke the Web Service" type="button" onclick="sayHello($('name').value,$('result'))" /><div id="container">Result:<div id="result"></div><div id="soap"></div></div></body> |
성공적인 호출은 Figure 3과 같은 결과를 만들어 낸다. 이 예제를 Mozilla, Firefox, Internet Explorer에서 실행하면 모두 같은 결과가 나온다.
그림 3. Firefox에서의 Hello World 예제

![]() |
![]()
|
Web Services JavaScript Library는 기본 SOAP 웹 서비스를 웹 애플리케이션에 통합하는데 사용될 수 있다. 다음 글에서는 라이브러리를 사용하여 WS-Resource Framework 스팩군에 기반한 고급 웹 서비스를 호출하는 방법과 웹 서비스 기능이 웹 애플리케이션으로 확장 및 통합되는 방법을 연구할 것이다.
![]() |
![]()
|
설명 | 이름 | 크기 | 다운로드 방식 |
---|---|---|---|
프로젝트 샘플 | ws-wsajaxcode.zip | 19 KB | HTTP |
![]() | ||||
![]() |
다운로드 방식에 대한 정보 | ![]() |
교육
- Ajax로 SOAP 웹 서비스 호출하기 -- 이 시리즈의 모든 Part 보기(영문).
- 동적 자바 애플리케이션 구현 (한글) -- Philip McCarthy의 자바 개발자를 위한 Ajax 소개 (한국 developerWorks, 2005년 9월).
- JavaScript 프레임웍
- XMLHttpRequest API
- Document Object Model을 활용하여 고급 웹 애플리케이션 만들기 -- Microsoft Internet Explorer 6.0을 사용한 XML 문서 객체 모델 (developerWorks, 2004년 2월).
- 모질라 웹사이트
제품 및 기술 얻기
- WebSphere Application Server: developerWorks에서 무료 시험판 다운로드.
토론
- developerWorks 블로그: developerWorks 커뮤니티 참여하기.
![]() | ||
|
![]() |
James Snell은 IBM의 WebAhead 개발 랩의 연구원이고, 여기에서 IBM 내부에서 사용할 소프트웨어 기술과 표준에 대한 프로토타입 개발을 수행하고 있다. 그의 관심 분야는 Atom, AJAX, REST, Open Source, 퍼스널 퍼블리싱 시스템, semantic web, situational application 등 광범위한 신 기술까지 포괄하고 있다. Apache Abdera의 활동적인 커미터이며, 최근에는 Atom Syndication Format과 Atom Publishing Protocol 표준의 구현 작업을 하고 있다. http://www.ibm.com/developerworks/blogs/dw_blog.jspa?blog=351. |
원문 출처 : http://www.ibm.com/developerworks/kr/library/ws-wsajax/
'Web > ajax' 카테고리의 다른 글
Ajax와 XML: 다섯 개의 추천할 만한 Ajax 위젯 (한글) (0) | 2009.01.12 |
---|---|
ASP.NET AJAX를 지원하지 않는 웹호스팅에 AJAX 사용하기 닷넷 (0) | 2009.01.12 |
Ajax와 XML: 최고의 Ajax 배우기 (한글) (0) | 2009.01.12 |
php java ajax 웹프로그래밍 기술서 출처 (0) | 2009.01.12 |
chaos@ecrobot.com
한상진 - komnaru@ecrobot.com
Source (주) 이씨로봇 연구소
Application magic_quotes_gpc 옵션이 Off인 상태에서 작동되는 DBMS연동 PHP 프로그램.
Risk Critical
Reference http://lab.ecrobot.com/advisories/ec2002080801
Last modified 2002/08/09
문의 info@ecrobot.com
차례
0x00. Overview
0x01. 해당 환경
0x02. DBMS를 연동하는 프로그램의 일반적인 구조
0x03. 공격이 이루어지는 원리
0x04. Exploit: 제로보드의 예
0x05. 해결책
0x06. ';' 문자를 이용한 SQL statement 조작
0x07. 결론
0x00. Overview
최근 웹 프로그래밍은 대부분 자료의 효율적인 저장 및 검색을 위해 DBMS를 거의 필수적으로 이용하는 추세이다. 웹 프로그래밍은 보통 PHP, JSP, ASP 등의 스크립트 언어를 이용하여 DBMS를 연동하여 프로그래밍을 하게 된다. 이러한 프로그램에서 생기는 문제점으로서, 잘못된 값을 웹 프로그램으로 넘겨줌으로써, 부적절한 SQL Query를 실행시키도록 할 수가 있다.
이 공격을 이용하면 불법적인 데이터베이스 query를 이용하여 인증을 위해 사용하는 SQL query 등을 비정상적으로 만들어서, 아이디나 암호가 맞지 않음에도 불구하고 인증을 정상적으로 한 것처럼 만들 수가 있다.
현재 대부분의 웹 기반 공개 게시판과 수많은 사이트들이 이 문제점에 노출되어 있는 것으로 확인되었다.
이 문서는 DBMS를 연동하는 웹 프로그램이 가질 수 있는 치명적인 문제점과 그 해결책에 대해 다룬다. 주로 PHP의 경우를 다루지만 다른 언어에서도 얼마든지 있을 수 있는 문제이다.
0x01. 해당 환경
이 문제점은 플랫폼과는 무관하다. 다만 PHP로 DBMS를 연동하는 경우, PHP의 설정에서 magic_quotes_gpc 옵션이 Off로 되어 있는 경우에 이 문제가 발생한다. 다른 프로그래밍 언어의 경우에도 사용자로부터 넘겨받은 데이터에 포함된 따옴표에 자동으로 escape처리가 되지 않는 경우에는 이 문제가 발생할 수 있다. 참고로 PHP 4.x 버전에 포함된 2개의 php 설정 파일 중, PHP 측에서 권장하는 설정 파일인 php.ini-recommend에는 성능상의 이유로 이 옵션이 기본적으로 Off로 설정되어 있어서 이 공격을 당할 수 있다.
0x02. DBMS를 연동하는 프로그램의 일반적인 구조
웹 프로그램은 HTML에서 form tag를 이용하여 사용자로부터 데이터를 입력 받고, GET이나 POST method를 이용하여 프로그램으로 데이터를 넘겨주면 프로그램에서 적절한 DBMS query를 통해 데이터 입출력을 하고 그 결과를 다시 사용자에게 보여주는 형태를 가지고 있다.
예로 ID와 암호를 입력받아 인증을 해주는 간단한 PHP 스크립트는 다음과 같은 형태를 가지고 있을 수 있다. 아래의 Login.html은 form tag를 이용하여 사용자로부터 id와 password를 입력받는 form을 출력하는 파일이고, login.php는 사용자가 입력한 데이터를 바탕으로 DBMS에 query를 하여 인증을 처리하는 프로그램이다.
- login.html
<html>
<body>
<form name="form1" method="post" action="login.php">
ID:
<input name="id" type="text" id="id">
<br>
Password:
<input name="passwd" type="text" id="passwd">
<br>
<input type="submit" name="Submit" value="Submit">
</form>
</body>
</html>
- login.php
<?php
$MySQL = mysql_connect("localhost", "user", "password");
mysql_select_db("database");
$result = mysql_query("SELECT id, passwd FROM user_table WHERE id='{$_POST['id']}' AND passwd='{$_POST['passwd']}'");
$data = mysql_fetch_assoc($result);
if (($data['id'] == $_POST['id']) && ($data['passwd'] == $_POST['passwd'])) {
/* 인증을 위해 세션 등을 설정 */
}
else {
/* 인증에 실패한 경우, 에러 출력 등의 처리 */
}
?>
위의 형태는 아주 일반적인 형태의 웹 프로그램으로 대부분의 프로그램이 이런 식으로 사용자로부터 받은 데이터를 이용하여 SQL query를 하고, 그 결과에 따라 특정한 처리를 하게 된다. 여기서는 사용자로부터 "id"와 "passwd"라는 2개의 데이터를 POST 방식으로 받아서, 프로그램 내에서는 $_POST['ID'], $_POST['passwd']와 같은 식으로 SQL query에 이용하고 있다(PHP에서는 이런 식으로 처리한다).
일반적인 경우에는 위와 같은 코드는 별 문제가 되지 않고 잘 작동할 것이다. 그러나 만약 php.ini 설정 파일에서 magic_quotes_gpc 옵션이 Off로 되어 있다면 아주 치명적인 문제점이 있다.
0x03. 공격이 이루어지는 원리
PHP의 설정 파일(php.ini) 중, magic_quotes_gpc 옵션이 하는 일은 사용자가 웹에서 입력한 데이터를 GET, POST으로 프로그램으로 넘겨줄 때나, 쿠키를 처리할 때에 ', ", \, 널 문자의 앞에 \를 하나 더 붙여 주어서 이러한 문자가 특수한 의미로 사용되지 않도록 escape시켜주는 것이다.
위에서 예로 든 코드 중 사용자가 입력한 id와 passwd라는 변수값을 SQL query에 넣어서 DBMS로 query를 하는 부분은 다음과 같다.
$result = mysql_query("SELECT id, passwd FROM user_table WHERE id='{$_POST['id']}' AND passwd='{$_POST['passwd']}'");
만약 사용자가 id로 chaos를, 비밀번호로도 chaos를 넣었다면 위의 코드는 사실상 다음과 같이 변환될 것이다.
$result = mysql_query("SELECT id, passwd FROM user_table WHERE id='chaos' AND passwd='chaos'");
원래 코드에 있었던 $_POST['id']와 $_POST['passwd'] 부분이 각각 chaos로 대체되면서 위와 같은 결과가 되는 것이다. 바로 이 부분에 헛점이 있다.
만약 사용자가 id로 chaos와 같은 정상적인 값을 넣지 않고 a' or 1<2 or 'a'<'b라고 입력했다고 가정해보자. php.ini에서 magic_quotes_gpc 옵션이 On으로 되어 있을 경우에 원래 코드는 다음과 같이 변환될 것이다.
$result = mysql_query("SELECT id, passwd FROM user_table WHERE id='a\' or 1<2 or \'a\'<\'b' AND passwd='chaos'");
이런 경우에는 저런 희한한 아이디가 있을리도 없고 암호가 맞을리도 없기 때문에 이 query는 아무 row도 반환하지 않고 그 결과 인증에 실패하게 된다.
그러나 이번에는 php.ini에서 magic_quotes_gpc 옵션이 Off로 되어 있는 경우를 가정해 보자. php.ini-recommend 설정 파일을 그대로 이용하는 경우가 바로 이 경우이다. 그러면 원래 코드는 다음과 같이 변환될 것이다.
$result = mysql_query("SELECT id, passwd FROM user_table WHERE id='a' or 1<2 or 'a'<'b' AND passwd='chaos'");
결론부터 얘기하자면 위의 SQL 문에서 WHERE clause는 항상 true이고, 모든 row를 반환하게 된다. 그렇게 되면 첫번째로 반환되는 row의 정보를 기반으로 로그인이 수행되게 된다. 왜 이 WHERE clause가 항상 true인가? 그것은 logical AND 연산이 logical OR 연산보다 우선순위가 높기 때문이다. 언뜻 보기에 위의 WHERE clause는 상당히 confusing해 보인다. 그러나 사실은 전혀 헷갈릴 것이 없이 매우 명확한 논리적 연산이다. 위의 SQL 문을 우선순위에 따라 단계적으로 괄호를 쳐보면 다음과 같다.
1: SELECT id, passwd FROM user_table WHERE id='a' or 1<2 or ('a'<'b' AND passwd='chaos')
2: SELECT id, passwd FROM user_table WHERE (id='a' or 1<2) or ('a'<'b' AND passwd='chaos')
1단계에서는 OR 연산보다 AND 연산이 우선순위가 높기 때문에 AND 쪽에 괄호를 쳤다. 그리고 나서 나머지 OR는 우선순위가 같은데, 이런 경우에는 앞에 있는 것이 더욱 우선순위가 높기 때문에 앞의 OR를 괄호로 묶었다. 이 상태에서 보면 앞의 괄호는 항상 true이다. "1<2" 연산 때문이다. 뒤에 괄호가 설사 false를 반환한다고 하더라도 이 두개의 결과가 or로 연결되었기 때문에 뒤의 괄호의 결과는 중요하지 않다. 이 WHERE clause는 항상 true인 것이다.
웹상의 로그인 form에 ID 등을 입력할 때 이런 식으로 ID를 교묘히 입력하면 SQL query 문을 비정상적으로 만들어서 아이디, 암호를 전혀 몰라도 아무 아이디로나 로그인이 가능하도록 할 수도 있고, 또한 아이디만 안다면 아이디만 적절히 지정하여 암호 없이 로그인을 통과할 수도 있다. 물론 대상 테이블 구조를 잘 알고 있다면 그 이상의 조작도 가능하다.
0x04. Exploit: 제로보드의 예
리눅스에서 인기있는 공개형 게시판 중 제로보드가 있다. 이 제로보드의 경우를 예로 들어, 이 공격을 실제로 테스트해 보겠다. 테스트 환경은 PHP 4.2.2(설정 파일로 php.ini-recommend 사용), 제로보드 버전 4.1 pl2이다.
위와 화면이 제로보드의 관리자 로그인 화면이다. 여기서 위와 같이 a' or 1<2 or 'a'<'b를 아이디 대신 입력하였다. 제로보드의 경우, 로그인을 체크하는 프로그램은 login_check.php이고 이 파일을 열어보면 인증을 하는 SQL query는 다음과 같이 적혀 있다.
$result = mysql_query("select * from $member_table where user_id='$user_id' and password=password('$password')") or error(mysql_error());
이런 경우에 아이디를 a' or 1<2 or 'a'<'b로 입력하고 암호는 아무것이나 입력하면 위의 SQL 문은 다음과 같이 변환된다.
select * from $member_table where user_id='a' or 1<2 or 'a'<'b' and password=password('asdfasdf');
이 SQL 문의 WHERE clause는 항상 true이며, 모든 row를 반환한다. 이런 경우에 맨 처음 반환되는 row에 의해 인증이 처리되도록 제로보드 프로그램이 만들어져 있다. 보통 게시판을 설치하면 관리자 아이디를 가장 먼저 만들게 되며, 그런 이유로 대부분 모든 row를 정렬없이 검색했을 때 관리자 아이디가 제일 먼저 반환되게 된다. 따라서 관리자로 로그인이 되는 것이다. 혹은 level=1인 row를 명시적으로 뽑아낼 수도 있을 것이다.
다음은 위와 같은 식으로 로그인을 한 결과이다.
여기서는 관리자 페이지만 테스트를 해보았으나, 일반 사용자 계정으로도 얼마든지 불법적인 로그인이 가능하다. 그런 경우에는 아이디만 지정하고 비밀번호는 아무것이나 적어도 통과시킬 수 있다. 또한 이 문제는 제로보드만이 가지고 있는 문제는 아니다.
0x05. 해결책
php.ini 설정에서 magic_quotes_gpc = On으로 설정하면 안전하다. 그러나 PHP 측에서는 performance 향상을 위해 이 옵션을 Off로 설정하도록 권장하고 있다. 또한 현재 PHP에서 권장하는 설정 파일에도 이 옵션이 기본적으로 Off로 되어 있다.
이 옵션이 Off로 되어 있는 상태로 프로그램을 작동시키고 싶다면 DBMS로 query를 전송하기 전에, SQL query statement를 만들기 위해 사용되는 변수들에 따옴표 등이 있는가를 확실히 체크하여 이 문자들을 escape시켜주도록 해야 한다.
한 예로, PHP에서 MySQL을 연동하는 경우를 위해 mysql_escape_string()이라는 함수를 제공한다. 이 함수는 따옴표와 같이 잘못된 MySQL query를 유발할 수 있는 문자에 대해 escape 처리를 해준다. 따라서 MySQL을 사용하는 제로보드의 경우 login_check.php 파일 앞부분을 다음과 같이 고치면 이 문제를 피할 수 있다.
$user_id = mysql_escape_string(trim($user_id));
$password = mysql_escape_string(trim($password));
위의 코드는 magic_quotes_gpc 옵션이 Off로 되어 있는 경우에만 사용해야 정상적으로 작동한다. magic_quotes_gpc 옵션이 On인 경우에는 이미 escape된 문자열에 또 escape 처리를 하게 되기 때문에 비정상적으로 작동하게 된다. 어느 경우에나 작동하도록 고치려면 get_magic_quotes_gpc()라는 함수를 이용하면 될 것이다.
오라클의 경우에는 ' 문자를 ''로 대체한 후에 SQL query를 작성하도록 하면 될 것이다.
제로보드의 경우, 윗 부분만 고쳤다고 해서 완전히 안전하다고 할 수는 없을 것이다. 다른 SQL query를 사용하는 수많은 부분에서 모두 잠재적인 위험이 있기 때문이다. 결국은 모든 게시판의 개발자 측에서 조치를 취해주는 것이 가장 바람직할 것이다.
0x06. ';' 문자를 이용한 SQL statement 조작
한번 더 생각해 보면, ID 등을 입력할 때에 아얘 ; DROP TABLE user_table; 등과 같이 입력해서 완전히 독립적인 SQL 문도 실행시킬 수 있지않을까 하고 생각될 수도 있다. 그러나 이 점은 안심해도 된다. PHP에서 MySQL로 query를 전송할 때에 ';' 문자가 포함되어 있으며 에러를 낸다.
0x07. 결론
PHP 언어가 버전 4.x 대로 넘어오면서 php.ini-recommend라는 설정 파일에 magic_quotes_gpc 옵션이 기본적으로 Off로 되어 있기 때문에, 기존의 설정대로라면 아무 문제없이 사용되던 게시판 프로그램 등이 보안 위험에 처하게 될 수 있다. 현재 만들어져 있는 많은 게시판 프로그램들이 PHP에서 자동으로 escape 처리를 해 줄것이라는 가정 하에 만들어졌기 때문에 이것이 더욱 위험한 것이다. 사실 이런 비슷한 유형의 문제는 예전에 perl로 웹 프로그래밍을 하던 시절부터 있던 문제였다. 다만 지금까지 PHP에서는 기본적으로 자동으로 특수 문자를 escape시켜주는 기능이 있기 때문에 보안 이슈가 되지 못했을 뿐이다.
또한 이 문제는 웹 프로그램에만 한정해서 생각할 문제는 아니다. C 언어로 system() 함수를 이용할 때에나 Perl 언어에서 `command`; 형식으로 다른 프로그램을 호출해서 사용할 때에도 항상 신중해야 한다.
만약 sendmail 프로그램을 호출하여 편지를 발송해주는 프로그램을 Perl이나 C 언어로 작성할 때에는 ; 문자를 조심해야 한다. 왜냐하면 만약 사용자가 이메일로 chaos@ecrobot.com; rm -rf / 이렇게 입력했다면 매우 심각한 문제를 가져올 수 있기 때문이다. 이런 경우에 sendmail chaos@ecrobot.com; rm -rf /과 같은 명령어가 쉘에서 실행되는 것이다.
'Hacking > web' 카테고리의 다른 글
쿠키해킹 개념 (0) | 2009.01.12 |
---|---|
토마토 님께서 3탄까지 올려서 뒤부분 올립니다. ^^* (0) | 2009.01.12 |
Web Hacking 4탄 쿠키취약점 (0) | 2009.01.12 |
[쿠키의 모든 것] (0) | 2009.01.12 |
[웹 모의해킹법 1-4] (0) | 2009.01.12 |