http://rifers.org 에서 발췌한 내용을 번역 하였습니다.
번역: 이원찬(wonchan.lee@gmail.com)
-------------------------------------------------------
Adding authentication
친구 데이터베이스 예제 어플리케이션은 이제 완벽한 웹어플리케이션이 되었다. 하지만, 누구나 데이터베이스에 친구를 추가할 수 있어 그리 유용하지 않다. 웹페이지에 이 프로그램을 올리고 누구나 읽을수 있도록 하되 목록은 우리만 관리할 수 있도록 하고싶다. 이말은 어떤 종류의 비밀번호 보안이나 인증이 반드시 필요하다는 의미이다.
인증(Authentication)
인증처리는 매우 일반적이며 RIFE는 사용자와 암호의 개념을 훌륭히 추상화하였다. 이제부터 보겠지만, 내장된 기능은 사용자의 목록을 XML파일과 나아가 데이터베이스로 관리할 수 있다.
데이테베이스 사용자
대부분의 사이트들은 사용자의 목록을 데이터베이스에 보관하길 원한다. 데이터베이스 사용자에 관해서는 다음장에서 별도로 다룰것이다. 이장의 나머지에는 간단히 메모리(memory)기반의 사용자를 사용한다. 어플리케이션은 사용자정보가 어디로 부터 발생하는지 관심을 두지 않는다. 그러므로, 개발단계에서는 메모리상에 사용자정보를 사용하다가 필요할때 데이터베이스로 변경하면 된다. 어떤 사람들은 설정이나 설치과정을 위해 메모리사용자를 사용하기도 한다. 이런 경우는 대부분 일부 몇안되는 사용자를 위한 기능이며 실행시에 변경되지 않는다.
메모리 사용자.
"메모리 사용자"는 사용자를 XML파일에 저장하기 위한 RIFE의 용어이다. (이름이 의미하듯 사용자정보는 초기화된 후 메모리상에서 유지된다.) 이것은 사용자를 관리하는 가장 쉬운 방법이며 관리자나 방문자(guest)사용자와 같은 고정된 그룹의 사용자들을 관리하는데 적합하다.
이 방법으로, 당신은 간단히 사용자와 비밀번호를 ParticipantMemoryUsers에서 지정된 파일에 쉽게 보관할 수 있다. 참여자를 추가하면서 시작해 보자:
------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rep SYSTEM "/dtd/rep.dtd">
<rep>
<!-- Add users participant -->
<participant param="rep/users.xml">ParticipantMemoryUsers</participant>
<participant param="rep/config.xml">ParticipantConfig</participant>
<participant param="rep/datasources.xml">ParticipantDatasources</participant>
<participant param="sites/friends.xml">ParticipantSite</participant>
</rep>
------------------------------------------------------------------
rep/users.xml은 사용자목록을 정의한 파일이다. 우선 관리자(administrator) 한명만 필요하며 이 사용자는 친구목록을 편집할 권한이 있다.
------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE credentials SYSTEM "/dtd/users.dtd">
<credentials>
<user login="admin">
<password>password</password>
<role>admin</role>
</user>
</credentials>
------------------------------------------------------------------
사용자명과 비밀번호(user and password)태그 이외에 role태그가 있다. 여기서는 admin롤을 부여하였다. 역할(role)은 사이트내 특정영역에 사용자에 따라 접근권한을 부여하기 위해 사용된다. role이 어떻게 사용되는지는 이장의 뒷부분에서 다루겠다.
인증을 설정하기 위해 몇단계를 더 거쳐야 하는데, 가장 좋은 방법은 어플레케이션에 기능을 추가/변경해 보는것이다.
사이트 구조 변경하기
관리자만 변경을 할 수 있으므로, 방문자는 아래의 옵션들을 볼 필요가 없다. 메뉴를 서브사이트로 나누는것이 첫번째 작업이다.
서브사이트 사용하기
RIFE의 사이트(site)는 더 작은 서브사이트(subsite)들로 구성될 수 있다. 서브사이트를 이용하면 사이트를 더 모듈화 할 수 있으며 또한 다른 어플리케이션의 일부로 재사용하기 쉬워진다. 이 예제에서, 우리는 관리자부분을 서브사이트로 만들고 거기에 인증메커니즘을 추가할 것이다.
이를위해, ADMIN요소를 고유의 사이트파일(sites/admin.xml)로 옮기고, 메인사이트 파일에 subsite태그로 서브사이트를 가리킬 것이다.
------------------------------------------------------------------
메인 사이트 파일
------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE site SYSTEM "/dtd/site.dtd">
<site>
<arrival destid="DISPLAY"/>
<element id="DISPLAY" file="display.xml" url="/display">
<flowlink srcexit="admin" destid="ADMIN"/>
</element>
<!-- Add a subsite -->
<subsite id="ADMIN" file="admin.xml" urlprefix="/admin"/>
</site>
------------------------------------------------------------------
이제 /admin 으로 시작하는 위치는 관리자 서브사이트에 의해 처리될 것이다. add, install, remove요소를 여기로 옮긴후 사이트파일은 아래와 같이 될것이다.
------------------------------------------------------------------
ADMIN 요소 서브사이트
------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE site SYSTEM "/dtd/site.dtd">
<site>
<globalexit name="menu" destid="MENU"/>
<arrival destid="MENU"/>
<element id="MENU" file="admin/menu.xml" url="/menu">
<flowlink srcexit="install" destid="INSTALL"/>
<flowlink srcexit="add" destid="ADD"/>
<flowlink srcexit="remove" destid="REMOVE"/>
<flowlink srcexit="back_to_display" destid=".DISPLAY"/>
</element>
<element id="INSTALL" file="admin/install.xml" url="/install"/>
<element id="ADD" file="admin/add.xml" url="/add"/>
<element id="REMOVE" file="admin/remove.xml" url="/remove"/>
</site>
------------------------------------------------------------------
서브사이트에서 메인사이트를 거꾸로 참조할경우 .DISPLAY로 대상을 성정했다. dot(.)은 구분자로 사용된다. 그러므로, 대상은 메인사이트의 요소를 가르킨다. 맨앞의 dot가 없을경우 링크는 상대적이여서 현재 서브사이트의 요소를 참조한다.
dot(.)구분자는 파일시스템에서 다렉토리명을 구분하기 위한 slash(/)와 비슷하게 사용된다. 예를들어, .ADMIN.REMOVE는 REMOVE와 같은 요소를 가르킨다. 하지만, 이런방법은 유연성을 떨어뜨리므로 권장하지 않는다.
디렉토리와 유사하게, 상위의 서브사이트 요소를 앞의 dot(.)없이 참조하는것도 가능하다. 두개의 dot(..)는 상위 디렉토리를 가르키는것으로 매우 친숙하다. RIFE에서는 ^ 기호를 사용할 수 있다. 이것은 .DISPLAY를 대신해 ^DISPLAY를 사용할 수 있음을 의미한다.
인증 요소
이제 실질적인 인증을 처리할때이다. 이 일을 하는 요소는 매우 쉽게 작성된다. 우리에게 필요한것은 RIFE의 내장된 요소인 rife/authenticated/memory.xml을 확장하는 것이다.
------------------------------------------------------------------
elements/auth.xml 인증요소
------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE element SYSTEM "/dtd/element.dtd">
<element extends="rife/authenticated/memory.xml">
<property name="template_name">auth.form</property>
<property name="role">admin</property>
<submission name="credentials">
<param name="login"/>
<param name="password"/>
</submission>
<childtrigger name="authid"/>
</element>
------------------------------------------------------------------
내장된 인증요소는 로그인 템플릿의 출력에서 처리를 포함해 모든 인증로직을 처리한다. 여기에 두개의 속성이 있다. 하나는 템플릿 파일을 가르키고, 다른 하나는 role을 지정한다. 이 간단한 어플리케이션은 단지 하나의 role만을 사용한다. 하지만, 이것은 사이트의 다른 부분에 매우 세밀한 접근제어를 필요로 하는경우 매우 강력한 도구로 사용될 수 있다.
요소늬 submission 패라미터는 통상적이나 childtrigger태그는 처음보는 것이다. 이것은 잠시후 설명할 것이다. 그전에, 로그인을 위해 폼을 추가하도록 하자.
로그인 폼
사용자명과 비밀번호를 입력할 폼을가진 템플릿이 필요하다. 여기 새로울것이 없는 평범한 폼이 credentials라는 이름의 submission으로 정의되어 있다.
------------------------------------------------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head><title>Admin</title></head>
<body>
<table cellpadding="5" cellspacing="0">
<tr valign="top" nowrap="1">
<td width="100%">
<h3>Please provide a login and password</h3>
<!--I 'auth.error_area'/-->
<form name="credentials" action="[!V 'SUBMISSION:FORM:credentials'/]"
method="post">
<!--V 'SUBMISSION:PARAMS:credentials'/-->
login<br/>
<input name="login" value="[!V 'PARAM:login'][!/V]" type="text"
size="18" maxlength="10" /><br/>
password<br/>
<input name="password" type="password" size="18" maxlength="10" /><br/>
<input type="submit" value="Login" /><br/>
</form>
</td>
</tr>
</table>
</body>
</html>
------------------------------------------------------------------
조합하기.
이제 관리자기능을 갖기위해 사이트를 재정의 하였고 인증처리를 위한 요소도 갖추었다. 이제 조합할 준비가 되었다. 이를 위해 RIFE의 강력한 기능중 하나인 상속을 사용할 것이다.
상속
RIFE어플리케이션의 요소(element)나 서브사이트(subsite)는 다른 요소로 상속을 할 수 있다. 이제부터 상속받은 요소를 "자식(child)", 상속하는 요소를 "부모(parent)"로 부르겠다. 상속은 부모의 processElement메소드가 자식의 processElement를 대신해 호출되는 특수한 경우에 작동한다.
RIFE는 이것을 매우 똑똑하게 처리하고 이 과정을 자식요소가 직접 관여하지 못하도록 한다. 부모요소는 전체사이트 구조의 일부분이 될 수 있다. 이것은 exits, accept, submission을 활성화 할 수 있고 상속을 사용하는 다른 요소로 이동할 수도 있다. RIFE웹엔진의 모든 기능은 부모로부터 감추어질 수 있다. 만약 그것이 arrival요소를 가지고 있다면 심지어 전체 서브사이트를 상속할 수도 있다. 경우에 따라, 상속에 제한을 걸어 자식이 활성화 되도록 하여 처음에 전달된 파라미터값을 받도록 할수도 있다.
우리의 경우, 관리자 사이트는 인증요소를 상속받는다. 사용자가 로그인하지 않았을경우, 부모요소가 보여질것이며 그렇지 않은경우 자식의 관리사이트가 보여진다.
자식 트리거(Child triggers)
RIFE엔진은 "childtrigger"라는것을 통해 부모와 자식중 하나를 결정한다. 우리는 인증요소에서 간단히 child trigger를 간략히 언급했었다. 부모요소의 childtrigger태그는 어떤 요소가 실행할지 결정에 사용할 변수 또는 쿠키의 이름을 기술한다. 트리거가 설정되지 않았으면, 부모의 procesElement메소드가 직접 호출된다. 설정되었을 경우에는 부모의 childTriggered메소드가 호출된다. 여기에서 트리거우 값이 옳은지 그른지를 확인할 수 있다.
이 모든과정은 얼핏 복잡하게 들린다. 하지만, 다행히도 이 모든 구현이 위에 우리가 확장한 메모리 사용자 인증 요소에서 구현되었다. 우리는 인증을 위한 별도의 처리를 전혀 할필요가 없었다. 그 이면에서 어떤일이 일어나는지를 아는것은 매우 유용하며 이를 더욱 발전시켜 커스텀요소를 만들어 child trigger를 구현할 필요가 있을때도 유용하다.
authid 변수 추가
인증요소의 childtrigger는 authid라는 변수이다. 우리는 sites/friends.xml 사이트 정의에 전역변수로 이를 추가하고 요소에서 사용할 것이다:
------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE site SYSTEM "/dtd/site.dtd">
<site>
<!-- Add authid variable -->
<globalvar name="authid"/>
<!-- Refer to the AUTH element definition -->
<element id="AUTH" file="elements/auth.xml" />
...
</site>
------------------------------------------------------------------
이제 관리자 서브사이트가 인증요소를 상속받기 위한 마지막 단계까지 모두 설정되었다.
인증요소 상속
아직 메인사이트에서 관리자 서브사이트를 분리하는것을 제외하고 원본 friends어플리케이션의 아무것도 변경하지 않았다. 사실, 그것은 상속의 장점이다: 여기엔 재작성하거나 요소나 서브사이트를 추가하지 않고 스스로 자식이 된다. 필요한것은 단지 sites/friends.xml의 서브사이트 정의만 수정하면 된다:
------------------------------------------------------------------
<subsite id="ADMIN" file="admin.xml" urlprefix="/admin" inherits="AUTH"/>
------------------------------------------------------------------
inherits="AUTH"만 추가하면, 관리자 사이트는 다른것을 변경하지 않고도 비밀번호로 보호된다.
마무리하기
Friends 어플리케이션은 아직 완전히 다듬어 지지 않았다. 아직 로그아웃할 방법도 없으며 사용자가 로그인중인지 아닌지를 가르키는 표시도 없다. 이제 로그아웃 링크를 추가하고 나머지는 독자를 위해 남겨두도록 하겠다.
로그아웃
내장된 인증요소를 사용해 로그아웃 요소도 포함한다. 로그아웃은 요소를 사이트에 추가하고 템플릿에 링크만 하면 된다.
------------------------------------------------------------------
<element id="LOGOUT" file="rife/logout/passthrough/memory.xml" url="/logout">
<flowlink srcexit="logged_out" destid="DISPLAY"/>
</element>
------------------------------------------------------------------
관리자 메뉴는 로그아웃 링크를 위한 좋은 장소이다.
------------------------------------------------------------------
<p><a href="[!V 'EXIT:QUERY:logout'/]">logout</a></p>
------------------------------------------------------------------
로그아웃 요소는 간단히 child trigger를 초기화 시킨다.
결론
이제 우리는 상속을 이용해 얼마니 쉽게 완성된 어플리케이션에 약간의 중재로 인증기능을 추가할 수 있는지 보았다. 이것은 어플리케이션은 인증을 제외하고도 개발및 테스트, 디버그 될수 있으며 나중에도 인증기능을 상속을 통해 추가할 수 있음을 보여준다
댓글 없음:
댓글 쓰기