상태가 없는 웹 어플리 케이션에서 인증을 구현하는 가장 간단한 방법은 무엇일까요?

가장 간단한 방법은 모든 HTTP 요청에 아이디와 비밀번호를 같이 보내는 것일거에요!
이런 방법을 Basic인증이라고 합니다.
Basic 인증에서는 최초 로그인한 후 HTTP 요청 헤더의 Authorization : 부분에 "Basic <ID>:<Password>'
처럼 아이디와 비밀번호를 콜론으로 이어붙인후 Base64로 인코딩한 문자열을 함께 보내는 거에요
이 HTTP 요청을 수신한 서버는 인코딩된 문자열을 디코딩해 아이디와 비밀번호를 찾아낸 후 사용자 정보가
저장된 DB또는 인증 서버의 레코드와 비교합니다.
DB의 레코드는 아이디와 비밀번호가 일치하면 요청받은 일을 수행하고, 아니면 거부하게 되는겁니다!

흠... 이 솔루션은 그러나 아이디와 비밀번호를 노출시키게됩니다...
??? : 아니, 인코딩을 했는데 왜 문제가 있는거에요?!
아쉽게도 인코딩은 보안을 목적으로 하는 것이 아닙니다... 비록 육안으로 아이디와 비밀번호를 찾아내기 힘들지만
디코더만 있다면 누구나 디코딩해서 원래의 아이디와 비밀번호를 확인할 수 있기 때문입니다...

따라서 Basic 인증은 HTTP와 사용하기엔 취약합니다. 중간에 누군가 HTTP 요청을 가로채 문자열을 디코딩하면
아이디와 비밀번호를 알아낼수있습니다.
이렇게 가로채는것을 MITM : Man In the Middle Attack 이라고 합니다.
따라서 반드시 HTTPS와 사용을 해야합니다.!!
또 이 솔루션을 사용하면 사용자를 로그아웃 시킬수 없습니다...
모든 요청이 일종의 로그인 요청이기 때문입니다.
우리는 '모든 디바이스에서 로그아웃하기' 같은 기능을 본적이 있습니다. ! 크롬이라던가 웨일이라던가 등
여러 디바이스에서 로그인이 가능한 경우 한꺼번에 로그아웃을 하거나 디바이스별로 로그아웃을 할 수 있는
긴능이 있는 애플리케이션이있습니다.
bASIC Auth를 이용하면 그런 기능을 제공하기 어렵게됩니다...

마지막으로 사용자의 계정정보가 있는 저장장소,
인증서버와 인증 DB에 과부하가 걸릴 확률이 높아집니다.
1초에 10만개를 처리하는 서버가 있다고 가정해보겠습니다.
10만개의 요청을 확인하려면 10만 번 계정 정보의 저장장소에 갔다 와야합니다.
까짓거 그냥 좋은 저장소나 좋은 DB를 쓰면 해결될것같지만!
규모가 작은 애플리케이션의 경우 굳이 스케일에 대해 고민할 필요가 생기게됩니다.
또 어느정도 까지 성능이 서버를 버티지 그 이후를 생각한다면 계속 비용을 늘려야한다.
이런 이유는 마이크로서비스로 쪼개지면서 인증 서버에 요청해야 하는 일이 너무 많아졌기 때문이다.
이것을 쉽게 이해하기 위해 정리를 스스로 해봤습니다...
한 애플리케이션에 독립된 서비스가 2개가 존재한다고 예를 들겠습니다.
클라이어트는 최초 로그인한 후 HTTP GET Todo 요청을 보냅니다.
서비스 2개중 1은 이를 인증 서버에서 인증을 합니다.
그리고 서비스 1은 서비스 2를 사용합니다.
서비스 1내에서 서비스 2에게 요청을 보낸다는 뜻입니다.
이때 HTTP 요청에 인증정보를 같이 보내야합니다.
그러면 서비스 2는 이를 위해 인증을 해야합니다.
그럼 요청에 벌써 2번 인증을 합니다.
서비스가 10개일경우 서비스 1이 나머지 9개의 서비스를 이용한다면 1개의 요청을 처리하려면 10번 인증을...
이럼 서버 과부하가 안걸릴수가없게될지도...
그리고 마지막의 단점은 인증 서버가 단일 장애점(Single Point of Failure)(시스템의 한부분이나 오류가 나는 경우 전체 시스템을 가동 불가능하게 함)이 된다는 점입니다.
'Spring boot 프로젝트 기록 > 기본적인 기초 공부' 카테고리의 다른 글
JSON 웹 토큰 (0) | 2021.12.11 |
---|---|
토큰 기반 인증 (0) | 2021.12.08 |
React 컴포넌트 (0) | 2021.12.02 |
React.js 가 뭐에요?ㅠㅠ (0) | 2021.12.02 |
브라우저의 동작 원리 (0) | 2021.12.02 |
댓글