무엇이 문제였을까?
로그인 기능을 구현하기 위해서는 어떠한 방법으로든 클라이언트를 식별할 수 있어야 합니다. 하지만 HTTP의 기본 원리를 그대로 따르면서 이를 구현하면 어려운 점이 많습니다. 무상태성을 완전하게 고려하면서 로그인 기능을 구성하려면 클라이언트는 매번 ID, PASSWORD를 보내주어야 할 것입니다. 이런 서비스를 사용하는 클라이언트는 매번 로그인을 해야할 것이구요.
그렇다면 쿠키에 ID, PASSWORD를 넣어두고 요청을 보내는 방식은 어떨까요? 사용자는 확실히 매번 요청을 할 필요도 없어보이고, 로그인 기능을 쉽게 구현할 수 있을 것 같아보입니다. 쿠키는 기본적으로 매 요청마다 같이 전송되니까요.
하지만 이 방식도 문제가 있습니다. 대표적인 문제점은 다음과 같습니다.
- 보안 위협: 요청에 그대로 민감한 정보가 실리기 때문에 요청을 '보낼 때마다' 보안 위협에 시달리게 됩니다.
- 성능 문제: 매번 요청이 들어올 때마다 ID, PW 정보가 있는 테이블에 접근을 해야하고, 복호화 과정을 거쳐 올바른 ID, PW를 가지고 있는지 검증해야 합니다. 조금 더 실무적인 관점으로 바라본다면, 매 요청마다 DB 쿼리 한 번이 더 날아간다는 것을 의미합니다.
그렇다면 어떻게 해야할까요? 현재 웹 어플리케이션에서는 크게 두 가지 방법을 통해 이 문제를 해결합니다. 첫번째가 세션 기반의 인증 방식이며, 두번째가 토큰 기반의 인증 방식입니다.
세션 기반의 인증 방식
세션 기반의 인증 방식에 대해 먼저 설명하겠습니다. 이는 인증을 구현하기 위해 전통적으로 사용되던 방법 중 하나입니다. 여기서는 예시를 통해 설명해보겠습니다. 클라이언트가 메일함 기능을 사용한다고 가정해볼게요.
세션이란, 유저에 대한 정보(로그인 만료시간 등)를 담고 있는 작은 파일입니다.
세션 기반의 인증 및 인가 방식을 사용하는 경우에는 위와 같은 플로우를 가지게 됩니다. 클라이언트는 처음에 로그인(ID, PW를 제공)을 하면 이후에는 ID, PW를 제공할 필요 없이 서버가 제공한 세션 ID를 통해서만 서버에 접근하면 되는거죠.
세션 기반의 방식을 사용하려면 서버는 어떠한 방식으로든 클라이언트에 대한 정보를 상태로 다뤄야 합니다. 즉, 세션 저장소라고 하는 개념이 필요해지게 되는 것입니다. 그리고 이 세션 저장소는 메모리나 DB를 통해 구현될 수 있습니다.
하지만 '세션 정보가 메모리나 DB에 저장되어야 한다'라는 제약조건 때문에, scale-out 시 이슈가 발생하기도 해서 유의해야 합니다.
토큰 기반의 인증 방식
세션 방식은 클라이언트의 상태를 서버가 관리하는 방식입니다. 반면 토큰 기반의 인증 방식은 클라이언트의 상태를 클라이언트가 직접 관리합니다. 이번에도 그림을 통해 표현해보겠습니다.
세션 방식의 flow와 크게 다르지 않습니다. 다른 점은 이번에는 인증 정보를 클라이언트가 직접 들고 있다는 점이죠. 클라이언트는 가지고 있는 토큰을 헤더에 실어서 보내면, 서버가 이를 검증하면서 토큰에 존재하는 인증 정보를 활용해 메일함 정보 반환 작업을 처리하게 됩니다.
이렇게 상태를 클라이언트가 직접 관리하면서 서버는 1. 검증, 2. 해독의 작업만 거치면 되기 때문에 앞서 이야기했던 scale-out에 유리합니다. 하지만 무상태성은 보장하나, 토큰 자체의 크기가 크기 때문에 이런 부분은 단점이라고 여겨질 수 있겠습니다.
세션 방식 vs. 토큰 방식
그렇다면 어떤 방식을 선택해야할까요? 표를 통해 간략하게 비교해보겠습니다.
세션 방식 | 토큰 방식 | |
네트워크 트래픽 | 작음 | 큼 (토큰 크기 자체가 크다. 기본적인 정보만 실어도 300바이트 이상) |
서버 상태 유무 | stateful 서버 | stateless 서버 |
인증 정보 저장 위치 | 서버 | 클라이언트 |
보안 | 안정적 (모든 정보를 서버에서 관리하기 때문에) |
취약 |
확장성(scale-out) | 불리 (Sticky Session, Session Clusturing, 세션 스토리지 분리 등을 수행해야 함) |
유리 |
클라이언트 제어 | 유리 (사용자를 로그아웃 시켜버린다거나, 여러 기기에서는 접속하지 못하게 막는게 가능) |
불리 (서버가 상태를 관리하지 않으므로, 클라이언트에 대한 제어가 어려움) |
위 내용을 통해 알 수 있듯, 세션 기반의 방식이나 토큰 기반의 방식 모두 고유한 한계점이 존재합니다.
하지만 각각의 고유한 한계점을 돌파하기 위한 방법들 역시도 존재합니다. 세션 방식의 경우 scale-out 이슈를 해결하기 위해 Redis를 외부 세션 저장소로 두기도 합니다. 결국 어느 방식을 선택하든 한계점에 대해 명확하게 인지하고 해결하려는 노력을 하는 것이 중요하겠다는 생각이 듭니다.
참고 자료
https://www.youtube.com/watch?v=1QiOXWEbqYQ
https://hudi.blog/session-based-auth-vs-token-based-auth/
https://www.geeksforgeeks.org/session-vs-token-based-authentication/
'웹' 카테고리의 다른 글
[Tomcat] maxThreads, maxConnections, acceptCount로 Tomcat 튜닝하기 (10) | 2023.09.08 |
---|---|
SOP(Same Origin Policy)와 CORS(Cross Origin Resource Sharing) (0) | 2023.08.22 |
JWT(Json Web Token) 개념 이해해보기 (2) | 2023.08.06 |
브라우저 저장소(쿠키, 로컬 스토리지, 세션 스토리지) 개념 알아보기 (1) | 2023.07.08 |