[JWT] 토큰 인증에 대하여

2025. 2. 28. 17:31·CS

JWT 토큰은 로그인 구현이라던지, API 개발에 많이 쓰여 개발하다보면 한번씩 접하게 된다. 오랜만에 JWT를 다루다가 고민했던 것들을 글로 남기면 좋을거 같아 기록하게 되었다.

 

- JWT란?

 

JWT(Json Web Token)란 Json 포맷을 이용하여 사용자에 대한 속성을 저장하는 Claim 기반의 Web Token이다. JWT는 토큰 자체를 정보로 사용하는 Self-Contained 방식으로 정보를 안전하게 전달한다.

 

- JWT 구조

 

 

 

 

 

JWT를 사용하기 위한 내용은 워낙 블로그 글이 많아 생략..


1. 어떻게 하면 Refresh Token과 Access Token을 잘 관리할 수 있을까?

 

-  Access Token은 인증 및 권한 부여에 사용하며, 상대적 짧은 만료 시간(15분 ~ 1시간)을 설정 하는 것

    • 클라이언트 측에서 API 요청 시 Authorization 헤더에 포함하여 사용

    • 토큰이 탈취되더라도 유효 기간이 짧아 피해를 최소화

 

- Refresh Token은 Access Token 을 발급 받기 위해 사용하고 재발급 시점에는 토큰을 재검증하여 보안을 강화 + Rotation & Blacklist

    • Refresh Token Rotation => 서버가 Refresh Token 을 통해 새로운 Access Token 을 발급시 새로운 Refresh Token 과 Access Token 을 

      함께 주는 전략
    •  Blacklist => 특정 Token 을 차단하기 위해 저장한 Token list 테이블 생성하여 관리하는 전략 

 

본인의 개발 환경을 고려하여 전략을 선택하면 된다.

 

2. 토큰 저장 시 클라이언트 측에서 XSS/CSRF 공격을 방지하기 위한 전략은?

 

- Refresh Token은 httpOnly 쿠키에 저장하여, JavaScript로 접근 불가능하도록 설정

- SameSite 속성을 Strict 또는 Lax로 설정하여, 외부 사이트에서의 요청을 차단

 

코드 예시

res.cookie('refreshToken', refreshToken, {
  httpOnly: true,
  secure: true, // HTTPS에서만 전송
  sameSite: 'strict', // CSRF 방지
  path: '/auth/refresh', // 특정 경로에서만 사용
  maxAge: 7 * 24 * 60 * 60 * 1000 // 7일
});

 

 

3. 만료 시 재발급 로직

 

1번) 클라이언트가 만료된 Access Token으로 API 요청.
2번) 서버는 토큰 만료를 확인하고, 401 Unauthorized 응답.
3번) 클라이언트는 /auth/refresh 엔드포인트로 Refresh Token 전송.
4번) 서버는 Refresh Token의 유효성을 검증하고, 새로운 Access Token 및 Refresh Token 발급.
5번 ) 클라이언트는 새로운 토큰으로 이전 요청 재시도.

 


*내가 개발 하면서 했던 고민의 흔적에 대한 결과물

(저는 JWT 토큰을 로그인 인증 전략으로 사용한게 아니라 특정 페이지에 접근할 권한이 있는지 판단하기 위하여 사용하였습니다. 로그인 인증 전략은 세션 쿠키 사용하였음.)

 

1. 로그인 시 AccessToken과 RefreshToken 반환 

 => 이때 AccessToken은 로그인 성공 body에 RefreshToken(암호화)은 Cookie로 전달

 

왜 RefreshToken을 클라이언트에 전달 하냐?, 만약 서버만 refreshToken을 가지고 있는다면 서버는 refreshToken이 살아있는 한 AccessToken을 무한정 찍어주는 역할밖에 하지 않는다. 그래서 RefreshToken을 클라이언트가 가지고 있어야 된다고 판단. 

 

2. AccessToken이 만료되면 새로운 AccessToken을 발급 받을 수 있는  API 생성 

 => 이때 클라이언트는 가지고 있는 Refresh Token을 전송해줘야 하고 서버에서는 Refresh Token 유효성 검증 및 새로운 AccessToken 전달

 

만약에 RefreshToken 까지 탈취를 당한다면?, 이를 보완하기 위해 AccessToken을 발급할때 이때 서버에서는 새로운 Refresh Token 발급한 다음 가지고 있는다. (Rotation 전략)  클라이언트가 들고 있는 refreshToken old 버전이고 서버에서는 new 버전을 들고 있으니 보안에 대한 문제점을 좀 더 해결 할수 있다. 

 

 

3. 엇? 그럼 Rotation 되는 시간동안 취약할 수도 있네?

보완해보자..

 

변경 전

✅ Access Token 갱신 흐름

  1. 유저가 Access Token을 갱신하기 위해 refresh_token_12345를 서버에 전송.
  2. 서버는 DB 에서 refresh_token_12345를 찾아서 User ID (user_001)를 가져옴.
  3. Refresh Token이 유효하면 바로 새 Access Token과 새 Refresh Token을 발급.
  4. 새로운 AccessToken을 유저에게 전송하고, DB에 바뀐 새 Refresh Token 저장.

변경 후

✅ Access Token 갱신 흐름 

  1. 유저가 Access Token을 갱신하기 위해 refresh_token_12345를 서버에 전송.
  2. 서버는 DB 에서 User ID (user_001)의 최신 Refresh Token (refresh_token_67890)을 가져옴.
  3. 유저가 보낸 refresh_token_12345와 DB에 저장된 refresh_token_67890을 비교.
    • ✅ 일치하면 정상적인 요청 → 새 Access Token과 새 Refresh Token 발급
    • ❌ 불일치하면 → 해킹 가능성 감지! → 비밀번호 변경 요청 등 보안 조치
  4. 새로운 Refresh Token (refresh_token_99999)을 Redis에 다시 저장.
  5. 새로운 AccessToken을 유저에게 전송하고, DB에 바뀐 새 Refresh Token 저장.

 

무슨 말이야?

 

 

간단히 다시 한번 정리를 하자면 UserID를 먼저 확인 한 다음 해당 User ID가 들고 있는 refreshToken 값이랑 현재 유저가 AccessToken 을 갱신하기 위해 전송한 RefreshToken 값을 한번 더 체크하는 것이다.


 

 

읽어주셔서 감사합니다!

 

저작자표시 비영리 변경금지 (새창열림)

'CS' 카테고리의 다른 글

개발자를 위한 필수 메모리 지식: 스택(Stack)과 힙(Heap) 이해하기  (0) 2025.05.05
[로드밸런싱] Load Balancing이란? 서버 부하 분산의 방법  (0) 2025.05.03
시간복잡도(Time Complexity) & 공간복잡도(Space Complexity)  (0) 2024.12.05
OOP vs FP 에 대하여..  (0) 2024.11.12
쿠키(Cookie)와 세션(Session)의 기본 개념  (0) 2024.10.13
'CS' 카테고리의 다른 글
  • 개발자를 위한 필수 메모리 지식: 스택(Stack)과 힙(Heap) 이해하기
  • [로드밸런싱] Load Balancing이란? 서버 부하 분산의 방법
  • 시간복잡도(Time Complexity) & 공간복잡도(Space Complexity)
  • OOP vs FP 에 대하여..
창MIN
창MIN
  • 창MIN
    미니의 코드
    만들고 도전하는것을 좋아합니다💻
  • Guest
    Gmail
    GitHub
  • 전체
    오늘
    어제
    • 분류 전체보기 (25)
      • Google Cloud (6)
      • NodeJS (3)
      • NestJS (1)
      • Python (1)
      • DB (1)
      • Docker & Kubernetes (1)
      • Server & Infra (3)
      • CS (7)
      • Algorithm (2)
        • 개념 (2)
        • 문제 (0)
      • 개발 (0)
  • 인기 글

  • 태그

    cloud buckets
    typeScript
    redoc
    Cors
    Cloud Storage
    Cloud Function
    signed url
    버킷 cors
    cors 작동
    Google Cloud
    cors 개념
    Secret Manager
    서버 부하
    파일 무결성
    google api gateway
    nodejs
    cloud logging
    알고리즘
    서버 부하 분산
    쿠키와 세션의 개념
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
창MIN
[JWT] 토큰 인증에 대하여
상단으로

티스토리툴바