728x90
토큰 기반의 인증 방식
- 토큰 기반 인증(Token-based Authentication)은 사용자 인증 후, 사용자에게 특정한 토큰을 발급하여 이후 요청 시 이 토큰을 통해 인증을 확인하는 방식
- 대표적으로 JWT(JSON Web Token) 같은 형태의 토큰이 많이 사용된다. 사용자가 로그인에 성공하면 서버는 사용자의 권한과 정보를 포함한 JWT를 발급하여 클라이언트에 전달한다.
- 클라이언트는 서버와 통신할 때마다 이 토큰을 포함하여 서버에 요청을 보내며, 서버는 토큰을 확인하고 요청을 처리한다.
세션 기반 인증과의 차이
- 세션 기반 인증에서는 서버에 사용자마다 세션 정보를 저장하고, 클라이언트는 세션 ID를 통해 인증을 유지한다. 클라이언트가 많아질수록 서버에 큰 부담을 줄 수 있다.
- 토큰 기반 인증은 서버에서 인증 상태를 저장하지 않아도 된다.(stateless) -> 서버는 클라이언트가 보유한 토큰만으로 요청을 검증하므로, 확장성이 좋고, 서버의 부담이 줄어든다.
Refresh Token의 필요성
why? 보안 상의 이유로 Access Token의 유효 기간을 줄이면서 사용자의 불편함이 생겨서
- Access Token은 비교적 짧은 만료 시간을 갖는다. 이 이유는 보안을 강화하기 위함인데, 만료 시간이 짧을수록 도난 시 피해가 줄어들기 때문이다. ( Access Token이 노출되면 사용자가 아닌 사람이 이를 사용할 수 있음. )
- 하지만 Access Token이 자주 만료되면 사용자가 로그인을 반복해야 하는 불편함이 생기기 때문에 Refresh Token이 필요하다.
Refresh Token의 역할
- Refresh Token은 더 긴 유효 기간을 가지고 있으며, Access Token이 만료되었을 때 새로운 Access Token을 발급받기 위해 사용된다.
- Refresh Token은 주로 서버 측에서만 관리하여, 사용자나 클라이언트가 이를 보관하지 않도록 한다.
- 하지만 refresh token을 사용하면 원래의 토큰 기반 방식의 stateless 특징을 좀 벗어나게 된다.
- Refresh Token을 Redis 등에 저장해 관리하면 서버는 각 클라이언트의 Refresh Token을 보유하게 되며, 이로 인해 약간 stateful한 특성이 추가된다. 서버가 각 사용자의 Refresh Token을 유지해야 하므로, 완전한 stateless 상태는 아니다.
Refresh Token을 관리하는 방법
- Redis 사용 : refresh Token은 빠르고 확장성이 좋은 Redis와 같은 인메모리 데이터베이스에서 관리하면 효율적이다. Redis의 TTL 설정을 통해 만료 기간을 관리하고, 분산 서버 환경에서도 일관된 상태를 유지할 수 있다.
- RDBMS를 사용할 경우, 토큰의 TTL 관리가 상대적으로 쉽지 않다. 주기적으로 토큰의 만료 여부를 확인하고 삭제해야 하므로 백그라운드 스케줄러가 필요할 수 있다.
- NoSQL은 확장성 및 유연성이 높아 토큰의 분산 저장이 용이하지만, TTL 관리 기능이 Redis보다 한정적이다.
- Blacklist 사용: 사용자가 로그아웃하고, 엑세스 토큰이 도난된 경우 블랙리스트에 추가해 악용을 방지할 수 있다. (자세한 내용은 아래를 참고하세요.)
Redis
- Key-Value의 형태의 데이터베이스이기 때문에 적은 메모리로도 데이터를 저장할 수 있으며, 작성 속도가 빠름
- Key-Value 형태를 가지고 있기 때문에 키를 알고 있다면 조회 성능이 O(1)까지 나온다는 장점을 가짐
- 인메모리 DB 방식으로 빠르게 접근이 가능
- In-Memory 데이터베이스는 다른 일반 DB들처럼 SSD, HDD와 같은 보조기억장치가 아닌, 프로세서가 직접 액세스할 수 있는 컴퓨터의 주 메모리인 RAM에 데이터를 저장한다.
- 원래는 HDD or SSD -> Load -> RAM -> Read -> CPU 하는 과정이 있어야 하는데 바로 인메모리 데이터베이스는 바로 RAM에 저장하기 때문에 빠르다.
- 휘발성인 In-Memory DB는 영구적으로 저장될 필요가 없는 Refresh token을 관리하기에 충분
- 캐시처럼 데이터 만료일을 정할 수 있음
도입 이유
- RDB와는 다르게 토큰의 만료일과 똑같이 맞춰두어 관리하면 토큰이 만료되면 Redis에서도 토큰이 삭제 (TTL 설정)
- 대체로 15분~2시간 단위로 갱신하는 JWT Access Token은 새롭게 갱신하기 위해 Refresh Token이 필요한데,
- 호출 빈도가 높은 refresh token은 RDB에 저장하는 것보다 In-Memory DB에 저장하는 것이 훨씬 효율적이다.
- BUT!! In-Memory DB는 휘발성 메모리이기 때문에 전원이 끊어지면 데이터가 전부 지워집니다.
- Refresh Token만을 관리하기 위해 Redis를 사용한다면? -> 단점이 커버될만한 장점을 갖고 있다.
- Refresh Token이 모두 삭제되었을 때 발생하는 가장 큰 사건은 모든 유저가 재로그인을 해야하는 문제가 발생한다.
- + 복제 구조를 통해서 바로 복구가 가능하게 해두면 괜찮을 수 있다.
Blacklist
도입 이유 : Access Token 유효기간과 보안 문제
- 사용자가 서비스에서 로그아웃할 때 Access Token과 Refresh Token을 삭제하더라도, Access Token의 남아 있는 유효기간 동안 탈취 위험이 존재한다.
이를 방지하기 위해 로그아웃 시 Access Token을 블랙리스트에 등록하여 남은 유효기간 동안만 이를 사용하지 못하도록 할 수 있다.
Blacklist?
- 블랙리스트는 로그아웃한 사용자의 Access Token을 별도로 관리하여, 해당 토큰으로의 인증을 차단하는 방식
- 로그아웃 시 Access Token을 블랙리스트에 추가하여 만료 시간을 설정해주면, 해당 기간 동안 이 토큰이 탈취되어 사용되더라도 서버에서 차단할 수 있다.
로직
- 로그아웃 요청
- 사용자가 로그아웃할 때 Access Token을 서버로 전송
- 블랙리스트에 추가
- 서버는 해당 Access Token을 Redis 블랙리스트에 저장.
- 이때 남은 유효기간만큼 TTL을 설정하여 Redis에 기록.
- TTL: 로그아웃 시 Access Token의 남은 유효기간
- 유효기간 이후 자동 삭제
- 유효기간이 지나면 Redis에서 블랙리스트가 자동으로 삭제되어, 시스템에 부하를 주지 않고 토큰을 관리
- 블랙리스트 조회
- 모든 요청마다 Redis 블랙리스트를 조회하여, 해당 Access Token이 블랙리스트에 있으면 요청을 거부.
- 탈취된 토큰으로 의심될 경우, 보안적으로 위험한 요청을 차단할 수 있음.
728x90
반응형
'WEB study > WEB(Springboot)' 카테고리의 다른 글
DB 설계 시 다대다(ManyToMany) 관계를 사용하면 안 되는 이유 (1) | 2024.11.21 |
---|---|
웹 쿠키와 세션 개념 및 활용 예시 (0) | 2022.03.05 |
Spring Boot와 MyBatis의 연동 - Maven 의존성 설정 (0) | 2022.03.04 |
Spring Boot와 MyBatis의 연동 - Data Access Layer의 개념 (0) | 2022.03.03 |
Spring Bean 개념과 의존성 주입 - Spring Service 계층, Spring Bean, 의존성 주입 (0) | 2022.02.23 |