Refresh Token 사용 이유와 Redis를 활용한 관리 방법: Blacklist, TTL, 보안 강화

2024. 11. 7. 15:15·WEB study/WEB(Springboot)
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을 블랙리스트에 추가하여 만료 시간을 설정해주면, 해당 기간 동안 이 토큰이 탈취되어 사용되더라도 서버에서 차단할 수 있다.

로직

  1. 로그아웃 요청
    • 사용자가 로그아웃할 때 Access Token을 서버로 전송
  2. 블랙리스트에 추가
    • 서버는 해당 Access Token을 Redis 블랙리스트에 저장.
    • 이때 남은 유효기간만큼 TTL을 설정하여 Redis에 기록.
      • TTL: 로그아웃 시 Access Token의 남은 유효기간
  3. 유효기간 이후 자동 삭제
    • 유효기간이 지나면 Redis에서 블랙리스트가 자동으로 삭제되어, 시스템에 부하를 주지 않고 토큰을 관리
  4. 블랙리스트 조회
    • 모든 요청마다 Redis 블랙리스트를 조회하여, 해당 Access Token이 블랙리스트에 있으면 요청을 거부.
    • 탈취된 토큰으로 의심될 경우, 보안적으로 위험한 요청을 차단할 수 있음.
728x90
반응형
저작자표시 (새창열림)

'WEB study > WEB(Springboot)' 카테고리의 다른 글

DB 설계 시 다대다(ManyToMany) 관계를 사용하면 안 되는 이유  (2) 2024.11.21
웹 쿠키와 세션 개념 및 활용 예시  (0) 2022.03.05
Spring Boot와 MyBatis의 연동 - Maven 의존성 설정  (0) 2022.03.04
Spring Boot와 MyBatis의 연동 - Data Access Layer의 개념  (1) 2022.03.03
Spring Bean 개념과 의존성 주입 - Spring Service 계층, Spring Bean, 의존성 주입  (2) 2022.02.23
'WEB study/WEB(Springboot)' 카테고리의 다른 글
  • DB 설계 시 다대다(ManyToMany) 관계를 사용하면 안 되는 이유
  • 웹 쿠키와 세션 개념 및 활용 예시
  • Spring Boot와 MyBatis의 연동 - Maven 의존성 설정
  • Spring Boot와 MyBatis의 연동 - Data Access Layer의 개념
pink_salt
pink_salt
유익함을 주는 개발자가 되도록 keep going
  • pink_salt
    KeepGoingForever
    pink_salt
  • 전체
    오늘
    어제
    • 분류 전체보기 (117)
      • Project (7)
      • WEB study (3)
        • WEB(Springboot) (10)
        • Git, GitLab (13)
        • Clean code (1)
        • FrontEnd (3)
      • Study (21)
        • Algorithm (19)
        • 면접 준비 (2)
      • Cloud Computing (2)
        • AWS (2)
      • 프로그래밍 언어 (35)
        • Java (29)
        • Python (0)
        • javascript (6)
      • 운영체제 (0)
        • Linux (0)
      • Database (4)
        • MongoDB (8)
        • SQL (8)
      • 애플리케이션 개발 (1)
        • Android (1)
      • AI (1)
        • Deeplearning (1)
        • machinelearning (0)
      • Daily (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    티스토리챌린지
    오블완
    MongoDB
    빅오표기법
    git branch
    IT교육
    코드프레소
    객체지향
    언어
    개념
    mysql
    무료코딩교육
    Query
    python
    gitlab
    백준
    코딩강의
    Database
    코딩이러닝
    대외활동
    SW
    Java
    spring boot
    자바
    dp
    Git
    codepresso
    SWEA
    BFS
    무료IT교육
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
pink_salt
Refresh Token 사용 이유와 Redis를 활용한 관리 방법: Blacklist, TTL, 보안 강화
상단으로

티스토리툴바