2007년 3월 25일 일요일

How to delegate openid

최근, 스프링노트의 delegation 문제에 대해 고민하다가(내가 왜... 남의 서비스에 대해 고민을... -_-a) OpenID 컨슈머 구현시 delegation 부분과 관련하여 더 나은 사용성을 제공하는 방법에 대해 생각해보게 되었습니다.

1. What is my OpenID?
아주 원초적인 문제입니다만, 나의 OpenID Account URL은 무엇일까요?
여기 eouia.myid.net이라는 OpenID Account를 가지고 있는 사용자가 하나 있다고 합시다. 이 사용자는 OpenID를 제법 잘 이해하고 있어서, 재미없는(?) myid.net이라는 도메인 대신 자신을 더 잘 identifying해줄 수 있는 http://dnzin.com을 delegated URL로 쓰고 있다고 하지요.

이제, OpenID인증이 필요한 곳마다, 이 사용자는, eouia.myid.net과 dnzin.com 두 가지 중의 한가지를 입력하는 선택을 해야 합니다. 사용자는 두가지 URL이 모두 유효하며 동일한 사용성을 가지는, 동등한 인식키라고 생각할 것입니다. 즉, dnzin.com은 eouia.myid.net의 alias라고 여기겠지요.

그렇다면, Consumer측에서는 이러한 사용자를 위해 어떻게 해야 할까요?
간단하게는
- 입력받은 URL을 방문해서 openid server와 delegation정보(만약 있다면)를 받아와 진짜 OpenID URL을 확인한 후, 해당 정보로 OpenID 인증을 시도합니다.

겉으로 보기에는 이것으로 끝이겠지만, 실제로 뒷단에서는 조금 골치아픈 일이 생길 수 있습니다.

이 사용자의 unique id로써 무엇을 DB에 저장해야 할까요? (계정을 생성하고 유지하기 위해서는 DB에 해당 사용자의 세션을 만들 필요가 있으므로...)

아마도 eouia.myid.net을 이 사용자에 대한 unique id로 잡는 것이 상식적일 것입니다.
그래야만, 사용자가 delegation을 바꾸더라도 동일한 account를 유지할 수 있을테니까요.
예를 들어, 사용자가 http://dnzin.com 대신, http://eouia.com으로 블로그를 바꾸면서 delegation도 바꾸었습니다. 이런 경우에도, 사용자는 delegation을 통해 새로운 http://eouia.com으로도, 새로운 가입절차 없이 이전과 동일한 계정에 로그인할 수 있기를 원할 겁니다.

따라서, Consumer측에서는 로그인시에, 입력받은 URL이 OpenID일거라고 가정하고 바로 DB에 저장된 값과 비교하는 대신, 반드시 해당 URL을 방문해서 delegation 정보를 획득하여 매번 OpenID 인증을 시도해야만 합니다.
현재 스프링노트에서는, 가입시에는 delegation 처리를 하지만, 로그인시에는 delegation 처리를 건너뛰고 있는 듯 합니다. 또는, 조금 있다가 따로 이야기 하겠지만, 사용자의 unique id로 실제 openid url대신 사용자로부터 최초 입력받은 url을 키값으로 쓰고 있을지도요. (버그 게시판의 답변을 미루어보자면 그런 듯... 실제로 안이 어떻게 구현되어있을지 저는 모르죠. ^_^)

여기까지는 가장 기본적인 Consumer 구현법입니다만, 실제로는 좀 문제가 있습니다.

2. How to change my OpenID?
이 사용자가 어느날, myid.net은 싫어... 라며 다른 OpenID Provider로 자신의 OpenID를 바꾸게 되었습니다. 그럴 일이 있겠냐구요? 어느날 myid.net이 없어지거나, 혹은 더 좋은 OpenID Provider가 생겼다거나, 혹은 myid.net이 SRE를 지원하지 않아 불편해.. 라고 생각할 수도 있겠지요.
그래서, eouia.newopenid.com이라는 새로운 OpenID 계정을 사용하기로 결심했습니다. 그래도 delegation을 통해 이전처럼 eouia.com이라는 url로 동일하게 로그인이 가능할 거라고 기대하겠지요. (delegation의 장점이죠.)

그런데, Consumer측에서는 문제가 생겼습니다. 사용자 계정 정보를 실제 OpenID URL(eouia.myid.net)을 키값으로 삼고 있었는데, 전혀 다른 새로운 OpenID URL(eouia.newopenid.com)이 들어오면 이것이 동일한 사용자라고 판단할 수 없기 때문입니다.

그렇다면, 역시 DB의 키값으로는 최초 입력받은 URL을 키값으로 삼는 것이 해결책이라고 생각할 수도 있겠지만... 이 경우에는 delegated URL을 바꿨을 때가 문제가 됩니다. (1번 참조)

결국, 이 사용자에 대한 unique id로 OpenID URL도, delegated URL도 사용하기 곤란한 상황이 됩니다.

3. multiple OpenID
그렇다면, 아예 DB의 유니크한 키값으로 URL을 쓰지 않는 방법이 가능하겠죠.

사용자는 언제든지 사용하고 있는 OpenID를 변경할 수 있고, delegate URL도 바뀔 수 있으며, 그 모든 경우에 대해 동일한 사용자로 인정받기를 원할 수 있습니다.
하지만 한편으로는, 동일한 OpenID에 대해 별개의 Persona의 개념을 원할 수도 있지요. (이 부분은 다른 기회에 다시...)

뿐만 아니라 인증 자체가 내가 컨트롤 할 수 없는 Provider쪽의 시스템을 이용하는 것이기 때문에, 별도의 안전장치를 필요로 합니다. 예를 들어, 어느날 갑자기 myid.net의 인증서버가 고장이 난다면, myid.net을 이용하던 사용자들은 다른 Consumer서비스를 전혀 이용할 수 없게 됩니다. 마른 하늘의 날벼락이죠. (OpenID Provider들이 더 늘어난다면 분명 이러한 문제가 생길 경우도 예상할 수 있습니다.)

따라서 친절한 Consumer라면 이러한 문제들을 해결하기 위해 다음과 같은 방법을 고려해야 합니다.
1) 하나의 계정당 복수개의 OpenID를 등록해서 사용할 수 있게 할 것.
2) 기존의 계정에 새로운 OpenID를 추가등록할 수 있게 할 것.
3) 물론 당연히 각각의 등록된 OpenID에 대해 delegation을 허용할 것.
4) 사용자가 등록된 OpenID를 삭제할 수 있을 것.

4)이 좀 이해가 안갈 수도 있을테니 부가설명 들어갑니다.
여기, eouia.com이라는 도메인을 가지고 있는 사용자가 있습니다. 자신의 OpenID로 eouia.com을 사용하고 있었는데, 깜박 잊고 도메인 연장을 하지 않아 타인에게 이 도메인을 빼앗겼습니다. 그 후, eouia.com을 획득한 타인이 역시 자신의 OpenID로 해당 도메인을 사용하고, 이를 이용해 이전 사용자의 인증을 도용한다면 어떻게 될까요. 이런 경우를 막기 위해서 사용자는 자신의 OpenID를 서비스에서 삭제할 수 있어야 합니다. (혹은, 추후 OpenID 스펙에, 해당 URL은 더이상 유효하지 않음을 Consumer들에게 알리는 프로토콜이 들어가는 방법도 있겠지요.)

4. Best Practice
어쨌거나 이러한 프로세스를 Consumer에서 제공하기 위해서는 사용자별로 OpenID를 unique id로 잡아서는 안되겠지요. 사실, openid만 사용가능한 서비스들(국내의 경우라면 스프링노트나 미투데이 등)은 아마 대부분 이런 식으로 구현될텐데, OpenID만 사용가능하게 하는 것이 사용자 정책적으로 전혀 바람직하지 않을 뿐더러, 실제로 운용에 있어 위에 언급한 바와 같은 문제점들이 발생할 수 있습니다. 그런 면에서 본다면, 왜 스프링노트나 미투데이 등이 OpenID 전용으로만 서비스하는지 조금 이해하기 어렵습니다. (정식 오픈때도 설마 OpenID전용은 아니겠지요.)

결론내리자면,
1) 단일 OpenID URL에 종속적인 인증은 사용자의 사용성을 저해할 수 있습니다.
2) 서비스 설계시 OpenID의 변경 가능성 및 복수 이용에 대해 열려있어야 합니다.
3) 결정적으로 OpenID에만 의존하는 인증방법은 바람직하지 않습니다. OpenID외에도 인증방법은 여러가지가 있을테니까요. (1년 서비스하고 말거면 뭐 상관없겠습니다만.)

댓글 없음:

댓글 쓰기