REST API를 사용한 폼 베이스 인증(Form Base Authentication)에 다이제스트 인증(Digest Authentication)을 적용하기 #1
주의: 폼 베이스 인증과 다이제스트 인증을 동시에 적용하는 건 큰 의미는 없다.특히 NGINX 등에서 제공하는 기본 인증방식(BASIC/DIGEST)을 사용할 시, 브라우저에서 제공하는 로그인 창이 출력되지 않게 하려면 사용자가 입력한 ID와 패스워드가 URL에 그대로 노출되게된다. 그러니 이러한 구현사항을 요청받았다면, 천천히 포기할 수 있게끔 설득해보도록 하자.
로그인 창으로 ID와 패스워드를 입력하면, 서버에서 임의의 세션값을 생성하여 사용자를 추적하게끔 설계되어있는 시스템이 있다. 즉, 폼 베이스 인증 방식을 사용하고 있었다. 이 시스템에 보안상의 문제가 있다며, 다이제스트 인증 방식을 사용하게끔 해달라는 요청이 들어왔다. 당장 폼 베이스 인증 방식이라는 말이 떠오르지 않았던 나는 잠시 정신이 아득해졌는데, 검색을 해보니 스크립트 단에서 헤더를 생성해주면 어떻게 우회할수도 있을 것 같았다. HTTP를 이용한 인증 방식 - BASIC, DIGEST, SSL, FORM, KENDRICK'S BLOG
일단 어려울 수 있겠다고 보고했지만, 빼도박도 못하는 문제가 생기는 것에 대비해서 솔루션을 찾아볼 필요는 있었다. 최악의 경우에는 폼 베이스 인증을 사용하지 않고, 다이제스트 인증 방식으로 돌려야 하는 경우도 생각해봐야했다. 그렇게되면 기존의 시나리오들이 모두 영향을 받아서, 정말 대공사가 되기 때문에 어떻게 해서건 그 경우는 막아야했다. 그래서 찾게 된 방법이 기존의 폼 베이스 인증 방식을 유지하면서, 다이제스트 인증 방식을 추가로 적용하는 방식이었다.
AJAX등을 이용한 HTTP 통신을 할 시 헤더에 다이제스트 인증 정보를 생성해주는 라이브러리는 꽤 있었다. 그 중 레거시 시스템에서 사용해야 할 경우를 대비하여, jQuery를 사용한 Kynec/digest-ajax를 사용하기로 했다. jQuery에 의존성이 있다는 건 조금 걸렸지만, 간단하게 테스트한 뒤 Vanilla JS를 사용하여 다시 구현하거나 라이브러리를 교체하는데 크게 시간이 소요되지 않을 거라는 판단하에 진행하기로 했다. 일단 POST로 데이터를 전송하기 위해서 다음과 같이 postDigest
를 호출했다.
DigestAjax.postDigest("\[RestAPI URI\]", {data:JSON.stringify(\[JSON DATA\])}, \[ID\], \[PW\])
일단 헤더값을 통해 네트워크로 오가는 데이터를 보니, 다이제스트 인증을 통과하는 게 확인됐다. 야호! 만일의 경우에는 이 방식을 이용해서 구현하는 것도 가능하겠다고 생각하는 순간, 다음의 문제점이 발견됐다.
![]()
앞에 말했듯이 URL에 사용자가 입력한 ID와 패스워드가 노출된다. 굳이 와이어샤크를 이용해서 패킷을 캡쳐해보지 않고, 크롬의 개발자 도구만 사용해도 사용자의 정보가 공개되는 셈이다. 사실상 보안상 허점이라고 해도 무방하다.
따라서 폼 베이스 인증을 유지하면서 HTTP 베이직/다이제스트 인증방식을 적용하려면, 서버의 코드를 이용해서 헤더에 직접 다이제스트 인증방식을 구현하는 것 외에는 방법이 없을 듯 하다.