GN⁺: JWT를 인증 토큰으로 사용해야 할까?
(blog.ploetzli.ch)- JWT는 JSON Web Tokens의 약자로, 인증된 토큰을 위한 표준임.
- JWT는 헤더, 페이로드, 서명 또는 메시지 인증 코드로 구성됨.
- 검증 키를 가진 사람은 페이로드의 진위 여부를 확인할 수 있음.
JWT의 일반적인 사용 패턴
- JWT는 발행자, 수신자, 주제, 만료 시간 등의 정보를 포함함.
- 수신자는 토큰의 진위 여부를 확인한 후, 만료 시간이 지나지 않았는지 확인하고, 주제를 인증된 사용자로 간주함.
JWT의 장점
- JWT의 주요 장점은 수신자가 사용자 데이터베이스에 연결하지 않고도 토큰의 진위를 확인할 수 있다는 점임.
- 대규모 설치 환경에서는 인증 서비스가 중앙 사용자 데이터베이스에 접근하는 유일한 서비스가 될 수 있음.
로그아웃 및 세션 무효화 문제
- 인증 토큰의 수명이 짧아야 함. 예를 들어, 최대 5분.
- 클라이언트는 새로운 인증 토큰을 요청할 수 있는 리프레시 토큰도 발급받음.
- 리프레시 토큰이 실제 세션 토큰 역할을 함.
JWT가 필요 없는 경우
- 로그아웃을 구현하려면 유효한 JWT의 허용 목록 또는 취소된 JWT의 거부 목록을 유지해야 함.
- 사용자를 차단하려면 데이터베이스에서 "사용자 활성" 플래그를 확인해야 함.
- 사용자 객체와 다른 객체 간의 추가 관계가 필요함.
- 데이터베이스와 관련된 작업을 수행함.
결론
- 위의 조건 중 하나라도 해당된다면, JWT가 필요 없음.
- 일반적인 불투명 세션 토큰을 사용하고 데이터베이스에 저장하는 것이 더 나음.
- JWT의 단점을 피하고 복잡성을 줄일 수 있음.
GN⁺의 의견
- JWT는 대규모 서비스에 적합하지만, 대부분의 소규모 서비스에는 과도한 복잡성을 초래할 수 있음.
- 일반적인 세션 관리 메커니즘이 대부분의 웹 애플리케이션에 충분함.
- JWT를 사용하면 로그아웃 및 세션 무효화와 같은 기능을 구현하는 데 어려움이 있을 수 있음.
- JWT의 장점을 활용하려면 서비스의 규모와 요구 사항을 신중히 고려해야 함.
- 다른 대안으로는 OAuth2와 같은 인증 프레임워크를 고려할 수 있음.
다양한 클라이언트 인증이 필요할 때 JWT 사용으로 얻는 이득이 많았습니다.
다만 확장성과 보안은 언제나 다른 방향을 바라보고 있기 때문에 보안이 특히나 중요하다면 다른 방법을 사용하는게 더 좋다고 생각합니다.
개인적으로 jwt 토큰은 공개되도 상관없는 임시데이터들을 브라우저 통해 시스템간에 주고받을때나 쓰고
인증에 사용되는 개인정보 담긴 토큰은 opaque 토큰을 쓰는게 낫다고 봅니다..
개인 경험에 비추자면 MVP 를 만들 때 JWT 의 이점이 있었습니다.
예를들어, 혼자서 만들고 유지하는 서비스라면 갑작스런 요청에 의한 기획비용을 줄인다는 생각인데요. 아무래도 처음에 세웠던 데이터 관계가 한 두달 뒤에는 완전히 달라져 버리다보니, 기획이 명확하게 나오지 않은 상태에서는 (auth 와 관련된 거 한해서) 차라리 JWT 페이로드 구성 시 옵셔널필드 형태로 가져가 피쳐 구현을 해놓으면, 기획단에서 도메인 분리랑 서비스 분리 업무를 하지 않아도, 일단 모놀리틱 서비스에서 도메인만 쉽게 분리하는 형태로 구현 후 시장 테스트 해볼 수 있었던 기억이 납니다. (그리고 추후 서비스를 분리하는 수순을 가져가는 겁니다. 아님 없애거나.)
그렇지만 만들고자하는 서비스의 도메인별로도 다를 거 같습니다. 해당 프로젝트는 실시간 서비스 중에서도 써드파티랑 결합도가 높은 프로젝트다보니....아무래도 빠르게 구현하다보면 디비에 엄청난 양의 도큐먼트/row 들이 쌓이거나하면 관리 비용이 커질 거 같다는 생각 하에 진행했던 기억이 있습니다.
물론, 빠르게 만드는데 집중하자면 세션 방식이 낫다고 봅니다. (초반에는 여러 서비스 간 커플링이 세지 않다보니 갈아엎고 다시 만들기도 편하고) 타 팀원 합류 시 인계비용도 적으니까요.
당시에는 잠깐이라도 이래저래 고민했습니다만, 사실 지금와서 돌이켜보면 어느쪽으로 구현 했든 프로젝트의 영향도가 심각하지는 않았을 거 같네요.
저는 개인적으로 api gateway를 쓸 때 auth구현을 jwt로 할 때 이득을 본다고 생각하는데, 작은 규모의 서비스에서 jwt가 갖는 이점이 어떤것이 있는지 궁금합니다. jwt에 담는 유저 정보를 자주 변경하는 케이스를 말씀하시는 것 인지요?
말씀하신 것과 큰 틀에서는 같습니다. 단지, 유저 자체에 대한 모델링이 바뀌어 정보를 자주 변경해야하기보다는 새로운 피쳐 추가나 서드파티툴을 이용해야하는 새로운 서비스가 부가적인 정보를 요구할 때 옵셔널하게 추가하는 경우에 가까웠습니다. (조금 더 하자면 잠재적으로 auth 를 api gateway 같은 걸 이용해서 관리단위를 분리할지 말지, 혹은 그와 준하는 역할을 하는 서버가 하나 있을지 미묘한 상황속에서...)
조금 구체적으로 예를 들면, A라는 서비스를 메인으로 가져가고 있는 상황이었는데요. MVP 다보니 결제정보나 인증된 유저인지 정보만 유저 테이블에서 가지고 있었습니다. 그런데 유저마다 다른 인증정보가 있어야 이용할 수 있는 서비스인 B와 C를 추가해달라는 요청이 들어온 상황이었습니다. 그중에서 또 B는 A라는 서비스 안으로 들어갈지 말지도 결정 안났고, C는 사라질수도 있어서 가볍게 테스트하고 싶어하는 상태였습니다. (플랜관리 기능은 말하지 않아도 추가해줘야 탈이 없었을 거고요). 이에 더해 B, C를 기존에 A 서비스를 제공하는 웹 서비스 페이지에서 같이 사용해보는 형태로 시작하고 싶어했습니다. 운영중인 서비스 특성상 플랜관리 테이블(혹은 범용적인 인증관련 테이블)을 만들어서 도메인 관계를 서비스마다 그려가지고 매핑해서 구현하기 전까지는 여러 개의 테이블 조회(혹은 콜렉션 조회)가 불가피한 상황이었습니다. 이게 프로젝트를 정리해줄 사람이 있는 상황에서는 몇 번 회의도 해서 도대체 해결하고자 하는 문제는 뭐고 원하는 피쳐는 뭔지 뾰족하게 뽑았으면 좋았겠지만, 그게 보장되는 상황은 아니었습니다. 또 언제 이런 부채들을 걷어낼 수 있는지 불투명하기도 했고요. 그래서 이런 일이 벌어질 법 했던게 A라는 서비스 런칭 전부터 조짐이 보였어서...첫 구성 때 auth 시 최대한 조회비용/추후 관리비용을 아낄 수 있는 형태로 가자 생각하다보니 JWT 로 했습니다. 그외에도 자잘하게 비슷한 일들이 워낙 많았던 거 같습니다.
하지만 댓 마지막에 언급했다시피 사실 뭘로 구현했어도 프로젝트 자체에는 아주 큰 영향은 없었을 거 같습니다. 세션으로 구현해놓았으면 세션 나름대로 방법을 찾았을 거 같아요. 오히려 개발자가 타 직무 일을 해야하는 상황이나 소통비용이 깨져야 하는 상황에 계속 노출되었던 게 훨씬 치명적이었던 거 같습니다.
- JWT가 활용될 수 있는 경우는 드물며, 대부분은 전통적인 세션 방식이 어울립니다.
- 생각보다 많은 개발자들이 JWT의 본질에 대해서 오해하고 있고, 여러 단점들을 간과한체 "이거 쓰면 DB 적게 쓴다더라, 성능이 빠르다더라" 라는 내용으로 커뮤니케이션 합니다.
- 그 커뮤니케이션에 빠지게 되면, 공개키 방식의 인증 및 전자서명의 본질부터 이해시켜야하는데 굉장히 골치 아파집니다.
- JWT는 고려 대상이 아니었는데, 블랙홀처럼 자꾸 회의를 이상한 방향으로 끌고가게 되었던 경험이 많습니다.
모놀리스 구조에 적합하더라도 일부서비스를 분기시키거나 확장의 기로에 놓일때 jwt와 세션 기반 로직은 분명한 차이를 보입니다. 단순히 인증 절차가 아닌 내부 로직의 사용성에서 데이터의 원천을 다루는 기법들이 달라질텐데 작은 서비스라는 컨텍스트를 어떤기준에서 적합하게 판단할지 잘 모르겠습니다. 모든 서비스는 반드시 작을거라는 전제인 것인지. 큰 서비스는 쉽지않을거라는 전제인지 모르겠습니다. 하지만, 항상 우리가 만드는 서비스에는 어떤 상황일지 모르는 하지만 여전히 유용한 컨텍스트를 지지하는 구조를 최소한으로 갖춰야 하지 않나 싶습니다. 작은 서비스의 전제는 계속 작아질 뿐일것 같습니다.
Hacker News 의견
해커뉴스 댓글 요약
- 전통적인 세션 메커니즘 사용 권장: 웹 프레임워크에서 제공하는 일반적인 세션 메커니즘을 사용하는 것이 좋음. JWT는 모든 상황에서 필요하지 않음.
- 마이크로서비스 아키텍처에서 JWT 사용: 마이크로서비스 환경에서는 JWT가 유용함. 단일 모놀리식 웹 앱에서는 필요성이 적음.
- JWT의 보안 문제: JWT가 보안에 취약할 수 있지만, 이는 잘못된 라이브러리 사용이나 설정 문제임. 신뢰할 수 있는 라이브러리를 사용하면 문제 없음.
- JWT 사용 경험: JWT를 사용하여 문제를 해결한 경험이 있으며, 후회 없음.
- AWS Cognito 사용: AWS Cognito를 사용하여 인증을 처리하면 MFA, 소셜 로그인, 이메일 인증 등을 쉽게 구현할 수 있음. JWT의 단점은 짧은 수명과 자주 갱신으로 해결 가능.
- 외부 서비스와 JWT: 외부 서비스에서 JWT를 자주 사용함. JWT를 사용하면 개발자들이 하나의 개념만 알면 됨.
- 작은 환경에서도 JWT 사용: 작은 환경에서도 JWT가 유용할 수 있음. 민감한 데이터 접근을 제한하고, 비용을 절감할 수 있음.
- JWT와 세션 토큰 비교: 많은 실제 JWT 배포는 JWT를 세션 토큰으로 교환함. JWT는 IDP가 사용자 신원을 확인하는 데 유용함.
- JWT의 장점: OAuth 2와 OIDC를 통해 인증 시스템을 표준화하고, 프론트엔드와 API 인증을 동일하게 처리할 수 있음.
- JWT 사용의 편리함: Azure와 같은 환경에서 JWT를 사용하면 세션 상태를 걱정할 필요 없이 여러 API에 접근할 수 있음.
- 기계 간 인증에서 JWT 사용: 기계 간 인증에서는 JWT가 가장 적합함. 예를 들어, Raspberry Pi 간의 통신에서 JWT를 사용하여 인증 및 권한 부여를 처리함.