Week 4

dOwny·2026년 5월 12일

Spring-Security

목록 보기
4/4

Session vs Token

사용자 규모 관점

세션은 각 사용자마다 세션 객체를 생성하지만, 토큰은 Stateless 했다.

따라서 사용자 규모가 크다면 인증 계층에서 낭비되는 메모리를 줄이기 위해 Stateless한 토큰 인증 방식을 쓰는 것이 좋다고 판단할 수 있다. 수백만 사용자의 동시 인증 요청도 토큰 방식을 쓰면 별도의 서버 증설 없이 감당 가능하다. 서버 재시작이나 배포 시에도 사용자의 인증 정보가 유실되지 않는다. 무중단 배포를 원활하게 할 수 있다는 장점이 있다.

다만, 사용자 규모가 작고 인증 계층에서의 메모리가 부담되지 않는 선이라면 세션 인증 방식을 고려하는 것이 좋다.

Scale Out

Scale Out은 트래픽이 많아질 때 동일한 사양의 서버 인스턴스를 여러 대 추가하여 시스템 전체의 부하를 분산하고 처리 능력을 확장한다.

Scale Up은 서버를 여러 개 추가하는 게 아니라 서버의 사양을 높이는 방식이다.

Scale Out을 할 때 Load Balencer가 Round Robin 같은 알고리즘으로 요청을 적절히 분산시켜준다. 따라서 로그인을 요청하는 서버가 다음 요청 서버와 다를 수 있다. 인스턴스 간에 메모리도 하나씩 다 있기 때문에 메모리를 공유하지 않는다. 각각 독립적으로 존재한다. 또한, 각 지표를 통해 Auto Scaling을 사용하여 서버를 활성화하거나 비활성화하여 자원을 아낄 수 있다.

만약 Scale Out 환경이라면 토큰 인증을 고려할 수 있다. 토큰 인증은 어차피 Stateless 니까 요청 서버가 각각 달라도 상관없다. 단, Session 방식이라면? 문제가 발생할 수 있다. 세션은 로그인 요청 서버에만 존재하기 때문에, 서버가 달라지면 사용자를 인식할 수 없다. 이걸 해결하기 위해 여러 해결법이 있는데,

  1. Sticky Session : 특정 사용자 요청은 항상 같은 서버로 보낸다. 하지만 서버가 죽으면 세션이 통으로 날아가며 트래픽 불균형 문제가 발생할 수 있다.
  2. Session Clustering : 서버끼리 세션 정보를 공유한다. 만약 A 서버에 특정 회원의 세션 정보가 등록되면 이 정보를 B 서버, C 서버에도 모두 복제한다. 서버 장애에 대응할 수 있지만, 서버 간 동기화 비용이 크다.
  3. External Session Storage : 세션을 Redis 같은 곳에 따로 보관한다. 가장 현실적인 방법이지만 별도 인프라를 운영해야 하고, 매 요청마다 외부 세션에 접속해야 하니 추가적인 I/O가 발생한다.

보안

보안 사고 유형

  1. Hijacking : 세션 ID나 토큰을 가로채서 해당 사용자로 둔갑한다.
  2. Escalation : 인증 정보를 조작하여 권한을 높인다.
  3. 내부자 위협 : 퇴사자가 퇴사 후에도 여전히 내부 시스템에 접근한다.

세션 인증은 세션 데이터가 서버에 모두 존재하기 때문에 서버가 제어권을 가진다. 따라서 보안 사고 감지 시 세션을 즉시 비활성화 할 수 있다. 토큰 인증은 한 번 발급된 토큰을 바로 무효화시키기 어렵다. 만료 시간 이전까지는 무효화할 수 없다. 블랙리스트? 결국 서버에 상태를 저장하는 것이니 Stateless가 무너지고, 이러면 그냥 차라리 세션 쓰는것이 맞다. 또한 암호화가 아닌 단순 Base64 인코딩/디코딩만 하기 때문에 토큰에 개인 정보를 넣으면 안 되며, 넣을 시 보안 사고가 발생할 수 있다.

개발 복잡도

세션 인증은 프레임워크가 대부분을 자동으로 처리해 준다.

하지만 토큰 인증은 개발자가 구현할 게 많다. 헤더나 페이로드에 어떤 것을 넣을 것인지, 만료 시간은 어떻게? 커스텀 필터는 어떻게? 이것들을 개발자가 모두 직접 구현해야 한다.

성능 지표

대표적인 지표

  • 응답 시간 : 클라이언트 요청 - 응답 시간
  • 메모리 사용량 : 인증 상태 저장에 소비하는 메모리
  • 네트워크 오버헤드 : 인증 과정에서 발생하는 추가적인 통신

세션 인증은 메모리 사용량과 네트워크 오버헤드에 영향을 미친다. 세션 정보가 서버에 저장되면 메모리 사용량이, Redis 같은 외부 저장소에 저장된다면 네트워크 오버헤드가 증가할 것이다.

토큰 인증은 토큰 서명 검증을 하기 때문에 응답 시간이 지연될 수 있다.

성능이 중요하다면 네트워크 오버헤드가 없고, 외부 저장소에 장애가 있어도 인증에는 영향이 없는 토큰 인증을 고려할 수 있다.

단일 서버 환경에서 인메모리로 쓰면 세션 인증이 빨라서 좋다. 하지만 Scale Out 환경이라면 외부 세션 저장소를 많이 쓸 텐데, 그렇다면 네트워크 오버헤드가 발생할 수 있고, Redis에 모든 요청이 몰리니까 병목 현상이 발생할 수 있다.

SPOF : 시스템 구성 요소 중 하나라도 고장 나면 전체 시스템이 멈추는 구조적 취약점

어떤 인증 방식을 적용했는가?

25-2 프로젝트에서 JWT 인증을 팀원이 구현한 적이 있다. 하지만, 테스트 도중 오류가 나면 열에 아홉은 JWT 인증 문제였다. 아주 까다로웠고, 매번 코드를 바꾸고 수정하고 예외사항에 뭘 넣고… 하다보니 토큰 방식에 선입견이 생겼다. 웬만하면 토큰 방식은 안하리라… 세션 방식을 프로젝트에 적용시켜 본 경험은 아직 없으나, 만약 프로젝트를 다시 시작하게 된다면 세션 방식으로 일단 구현할 것이다.

profile
그냥 기록용... (모든 글은 본인이 직접 고사리같은 손으로 타자 칩니다.)

0개의 댓글