이 영역을 누르면 첫 페이지로 이동
쿄코코 블로그의 첫 페이지로 이동

쿄코코

페이지 맨 위로 올라가기

쿄코코

얼레벌레 생활🤯

JWT(Json Web Tool) 작동원리와 Refresh Token

  • 2025.02.11 00:06
  • Study Platform📚/그림으로 배우는 Http&Network Basic
    반응형

    1. JWT란?

    JWT(JSON Web Token)는 JSON 기반의 인증 토큰으로, 사용자의 인증 및 권한 부여를 위해 사용된다.
    서버와 클라이언트 간의 안전한 정보 교환을 목적으로 하며, 디지털 서명을 포함하여 위변조를 방지할 수 있다.

    • 무상태(Stateless) 인증 방식 지원 : JWT는 서버에 세션 정보를 저장할 필요 없이, 토큰 자체에 인증 정보를 포함.
    • 서비스 간 인증과 보안성 강화 : API Gateway에서 JWT로 인증 후 내부 서비스에서 추가 인증 없이 처리 가능.
    • 확장성 높은 인증 구조 : 새로운 마이크로서비스가 추가되어도 기존 인증 시스템을 변경할 필요 없음.
    • Third-Party 및 Single Sign-On(SSO) 지원  : OAuth 2.0, OpenID Connect 등과 연동 가능하여 타사 서비스 인증 쉽게 통합. 한 번 로그인하면 여러 마이크로서비스에서 동일한 인증을 활용 가능.
    • 부하 분산 및 성능 최적화 : 클라이언트가 한 번 발급받은 JWT를 재사용할 수 있어 서버 부하 감소.DB 조회 없이 토큰 검증만으로 인증 가능하여 성능 향상

    👉 결론: JWT는 MSA 환경에서 무상태 인증, 부하 분산 및 성능 최적화, 보안성, 확장성을 제공하는 강력한 인증 방식.

    2. JWT의 구조

    JWT 구조 예시 (출처: BizSpring)

    JWT는 "."(점)으로 구분된 세 개의 부분으로 구성된다.

    1️⃣ 헤더(Header)

    사용하는 키(kid), JWT의 사용할 타입(typ), 서명 암호화 알고리즘(alg)의 정보가 담겨 있다.

    { 
      "kid": "KEY ID" //서명시 사용하는 키(Public/Private Key)를 식별하는 값
      "typ": "JWT" // 토큰 타입 
      "alg": "HS256", // 서명 알고리즘 (예: HS256, RS256 등) 
    }

    2️⃣ 페이로드(Payload)

    사용자의 정보(클레임, Claim)가 담긴 부분이다.
    이 정보는 암호화되지 않으므로 민감한 데이터는 넣으면 안 된다

    {
      "sub": "1234567890",  // 사용자 ID (주제, subject)
      "name": "John Doe",   // 사용자 이름
      "iat": 1516239022,    // 발행 시간 (Issued At)
      "exp": 1516242622     // 만료 시간 (Expiration)
    }
    Claim 의미
    iss (Issuer) 발급자 정보 (예: auth.example.com)
    sub (Subject) 사용자 ID 또는 주제 (예: user123)
    aud (Audience) 대상(클라이언트) (예: myapp.com)
    exp (Expiration) 토큰 만료 시간
    🔹 설정하지 않으면 무제한 사용 가능하므로 주의!
    iat (Issued At) 토큰 발급 시간
    nbf (Not Before) 특정 시간 이후에만 유효

    3️⃣ 서명(Signature)

    JWT의 무결성을 검증하기 위한 서명 값이다.

    Header(헤더)+ 페이로드(Payload)와 서버가 갖고 있는 유일한 key 값을 합친 것을 헤더에서 정의한 알고리즘으로 암호화한다.

    Header(헤더)와 Payload(페이로드)는 단순한 Base64Url 인코딩일 뿐, 암호화되지 않는다.

    그렇기에 제 3자가 디코딩하여 내용을 볼 수 있으며, 심지어 조작할 수 있다. 

    하지만, Signature는 서버의 비밀키(Secret Key)를 사용하여 생성되므로, 비밀키가 유출되지 않는 이상 제 3자가 복호화하거나 위변조 할 수 없다. 즉, 서명(Signature)은 JWT의 위변조 여부를 검증하는 핵심 요소 이다.

    HMACSHA256(
      base64UrlEncode(Header) + "." + base64UrlEncode(Payload),
      secretKey
    )

    👉 결론: JWT는 MSA 환경에서 무상태 인증, 성능 최적화, 보안성, 확장성을 제공하는 강력한 인증 방식.


     

    3. JWT의 동작 방식

    1. 사용자가 로그인 요청 → 서버에서 사용자 인증 후 JWT 발급
    2. 클라이언트는 JWT를 저장 (예: LocalStorage, Cookie 등)
    3. API 요청 시 JWT를 포함 (예: Authorization: Bearer <JWT>)
    4. 서버에서 JWT 검증 후 사용자 요청 처리
    5. JWT 만료 시 갱신 필요

     

    4. JWT 예제 

    1)  JWT 생성

    import jwt
    import datetime
    
    # 비밀키 설정
    secret_key = "my_secret"
    
    # 페이로드 데이터
    payload = {
        "iss": "example_issuer",
        "sub": "example_user",
        "name": "John Doe",
        "claims" : {"role": "admin", "department": "IT"}, # 사용자 정의 클레임
        "iat": datetime.datetime.utcnow(),
        "exp": datetime.datetime.utcnow() + datetime.timedelta(hours=1)
    }
    
    # JWT 생성 (HS256 알고리즘 사용)
    token = jwt.encode(payload, secret_key, algorithm="HS256")
    print(token)
    
    #출력
    #eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJleGFtcGxlX2lzc3VlciIsInN1YiI6ImV4YW1wbGVfdXNlciIsIm5hbWUiOiJKb2huIERvZSIsImNsYWltcyI6eyJyb2xlIjoiYWRtaW4iLCJkZXBhcnRtZW50IjoiSVQifSwiaWF0IjoxNzM5MTk4NzY5LCJleHAiOjE3MzkyMDIzNjl9.rzpj64WybEHEXZMhDHU2-jvqgI2cIrZ7fRQwR1PRGyU

     

    2) https://jwt.io 해당 사이트를 통해 확인 가능하다.


     

    5. JWT vs. 세션 기반 인증

    특징 JWT(토큰 기반) 세션 기반 인증
    상태 관리 Stateless (서버 저장 불필요) Stateful (서버 세션 저장 필요)
    성능 빠름 (서버 부하 적음) 비교적 느림 (세션 저장 필요)
    확장성 높음 (다른 서비스에서도 사용 가능) 낮음 (서버에 종속)
    보안 탈취 시 위험, 재사용 가능 서버에서 세션 만료 가능
    • JWT는 분산 시스템에서 유용 (예: 마이크로서비스, 모바일 API 인증).
    • 세션 기반 인증은 보안 관리가 더 쉬움 (예: 전통적인 웹 애플리케이션).
    • 세션 기반 인증은 만약 세션 ID가 탈취당하면, 서버 개발자는 해당 세션 ID를 서버에서 강제로 만료시킬 수 있다. 즉, 서버는 세션을 관리하기 때문에 유효성 검증과 즉각적인 대응이 가능하다.
    • 하지만, 만약 세션 JWT 가 탈취되면, 서버 개발자가 알아채더라도 기존 토큰을 강제로 만료시킬 방법이 없다. JWT 자체에 유효 기간 (exp)이 포함되어 있으므로, 서버는 그 유효 기간이 끝날 때까지 이를 막을 방법이 없다. 이 단점 때문에 토큰 기반 인증에서는 리프레시 토큰이 필수로 사용된다.

     

    6. 리프레시 토큰 ❓

    유효기간이 다른 JWT 토큰 2개(Access Token과 Refresh Token)을 두는 것이다.

    리프레시 토큰은 액세스 토큰(Access Token)의 갱신을 위한 토큰이다. 
    액세스 토큰(Access Token)은 수명이 짧고, 리프레시 토큰은 비교적 긴 수명을 가지는 것이 일반적입니다.

    통신과정에서 탈취당할 위험이 큰 Access Token의 만료 기간을 짧게 두고 Refresh Token으로 주기적으로 재발급함으로써 피해을 최소화한 것이다.

    리프레시 토큰 방식

    1. 액세스 토큰 발급
      • 사용자가 로그인하면 서버는 액세스 토큰(단기)과 리프레시 토큰(장기)을 발급한다.
      • 액세스 토큰은 클라이언트가 API를 호출할 때 사용하며, 짧은 유효 기간을 가진다.
    2. 토큰 갱신 과정
      • 액세스 토큰이 만료되면, 클라이언트는 리프레시 토큰을 사용해 새로운 액세스 토큰을 요청한다.
      • 서버는 리프레시 토큰이 유효한지 확인한 후, 새로운 액세스 토큰을 발급한다.
    3. 탈취된 토큰 대응
      • 리프레시 토큰은 서버에 저장되거나, DB에서 유효성을 확인하기 때문에, 서버 개발자가 탈취된 리프레시 토큰을 강제로 만료시킬 수 있다. 이로 인해, 탈취된 액세스 토큰의 피해를 최소화할 수 있다.
    반응형

    'Study Platform📚 > 그림으로 배우는 Http&Network Basic' 카테고리의 다른 글

    그림으로 배우는 Http&Network Basic 정리 - 5장. HTTP와 연계하는 웹 서버  (0) 2025.02.18
    그림으로 배우는 Http&Network Basic 정리 - 4장. 결과를 전달하는 HTTP 상태 코드  (0) 2025.02.16
    그림으로 배우는 Http&Network Basic 정리 - 3장. HTTP 정보는 HTTP 메세지에 있다  (1) 2025.02.12
    그림으로 배우는 Http&Network Basic 정리 - 2장. 간단한 프로토콜 HTTP  (0) 2025.02.11
    그림으로 배우는 Http&Network Basic 정리 - 1장. 웹과 네트워크 기본에 대해 알아보자  (0) 2025.02.06

    댓글

    이 글 공유하기

    • 구독하기

      구독하기

    • 카카오톡

      카카오톡

    • 라인

      라인

    • 트위터

      트위터

    • Facebook

      Facebook

    • 카카오스토리

      카카오스토리

    • 밴드

      밴드

    • 네이버 블로그

      네이버 블로그

    • Pocket

      Pocket

    • Evernote

      Evernote

    다른 글

    • 그림으로 배우는 Http&Network Basic 정리 - 4장. 결과를 전달하는 HTTP 상태 코드

      그림으로 배우는 Http&Network Basic 정리 - 4장. 결과를 전달하는 HTTP 상태 코드

      2025.02.16
    • 그림으로 배우는 Http&Network Basic 정리 - 3장. HTTP 정보는 HTTP 메세지에 있다

      그림으로 배우는 Http&Network Basic 정리 - 3장. HTTP 정보는 HTTP 메세지에 있다

      2025.02.12
    • 그림으로 배우는 Http&Network Basic 정리 - 2장. 간단한 프로토콜 HTTP

      그림으로 배우는 Http&Network Basic 정리 - 2장. 간단한 프로토콜 HTTP

      2025.02.11
    • 그림으로 배우는 Http&Network Basic 정리 - 1장. 웹과 네트워크 기본에 대해 알아보자

      그림으로 배우는 Http&Network Basic 정리 - 1장. 웹과 네트워크 기본에 대해 알아보자

      2025.02.06
    다른 글 더 둘러보기

    정보

    쿄코코 블로그의 첫 페이지로 이동

    쿄코코

    • 쿄코코의 첫 페이지로 이동

    검색

    메뉴

    • 홈

    카테고리

    • 분류 전체보기 (172)
      • Python (24)
        • 😈 99클럽 코테 스터디 4기 TIL (23)
        • 궁금한거 정리 (1)
      • SQL (16)
        • HackerRank (15)
      • [백준] Python,Java로 풀기📖 (71)
        • 정렬(Sorting) (6)
        • 그리디 (5)
        • 문자열 (7)
        • 수학 (3)
        • DFS&BFS (10)
        • 구현 (4)
        • 다이나믹 (17)
        • 이분탐색 (1)
        • 자료구조 (10)
        • 최단거리 (5)
        • 인덱스트리 (0)
      • [프로그래머스]Python,Java로 풀기 (6)
        • Level 1 (4)
        • Level 2 (2)
      • Study Platform📚 (28)
        • 김영한👨🏻‍🏫의 스프링 부트와 JPA 실무 완전 .. (5)
        • (알고리즘)- [이코테] 이것이 코딩테스트다 정리 (10)
        • 그림으로 배우는 Http&Network Basic (10)
        • AWS SAA C03공부하기 (3)
      • 까먹을까봐 적는 것들 (5)
      • 테스트 보고 난 후..🤔 (0)
      • kt 에이블스쿨 (18)

    최근 글

    인기 글

    댓글

    공지사항

    아카이브

    태그

    • 프로그래머스
    • 오블완
    • TiL
    • 코딩테스트준비
    • 99클럽
    • 티스토리챌린지
    • 항해99
    • 백준

    나의 외부 링크

    정보

    쿄코코의 쿄코코

    쿄코코

    쿄코코

    블로그 구독하기

    • 구독하기
    • RSS 피드

    방문자

    • 전체 방문자
    • 오늘
    • 어제

    티스토리

    • 티스토리 홈
    • 이 블로그 관리하기
    • 글쓰기
    Powered by Tistory / Kakao. © 쿄코코. Designed by Fraccino.

    티스토리툴바