TIL_JWT_241121

2024. 11. 21. 23:54·Spring 단기심화 2기

JWT (JSON Web Token)

개념

JWT (JSON Web Token)
사용자 인증 및 정보 전달을 위해 JSON 형식으로 데이터를 안전하게 인코딩하여 생성된 토큰입니다.

JWT 구조

JWT는 Header, Payload, Signature 3부분으로 나뉘어 있으며 . 으로 구분됩니다.
형식 : xxxxx.yyyyy.zzzzz

  1. Header는 토큰의 타입과 사용된 서명 알고리즘을 나타냅니다.

     { 
       "alg": "HS256", 
       "typ": "JWT" 
     }
  2. Payload는 사용자의 정보나 속성을 나타내는 Claim이 담겨있습니다. 즉, 보내고자 하는 데이터 자체를 의미합니다.

     { 
       "sub": "1234567890", 
       "name": "John Doe", 
       "admin": true 
     }
  3. Signature는 인코딩된 헤더와 페이로드를 비밀키 및 헤더에 지정된 알고리즘을 사용해 생성된 값으로, JWT의 무결성과 신뢰성을 검증하는 역할을 합니다.

     HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

등장 배경

기존에 사용하던 인증 방식인 Cookie와 Session의 단점을 보안하기 위해 JWT가 등장했습니다.

보안 이슈

XSS (Cross Site Scripting)

  • 사용자를 대상으로 한 공격으로, 게시판이나 웹메일 등에 악성 스크립트 코드를 삽입하여 개발자가 의도하지 않은 기능을 실행하게 만드는 보안 취약점 공격입니다.
  • 주로 쿠키, 토큰, 기타 중요한 정보를 훔치는 용도로 사용됩니다.
  • 스크립트로 접근할 수 있는 곳에 토큰이 저장되어 있으면 XSS 공격에 취약해집니다.
    • localStorage
    • httpOnly로 설정되지 않은 Cookie

CSRF (Cross Site Request Forgery)

  • 사용자가 자신의 의도와는 무관하게 공격자가 의도한 행위를 서버에 요청하게 하는 공격입니다.
  • 사용자가 이미 로그인되어 있고, 브라우저가 요청 시 자동으로 쿠키를 전송하는 점을 악용합니다.

JWT 저장위치
프론트에서 보통 SessionStorage, LocalStorage, Cookie에 보관됩니다.

  • SessionStorage
    새로고침 및 탭이 닫히면 데이터가 사라지기 때문에 사용자 경험 측면에서 탈락

  • LocalStorage
    스크립트로 접근 가능, XSS 취약
    LocalStorage에 저장된 JWT는 브라우저가 자동으로 서버에 보내지 않으므로 CSRF는 안전

  • Cookie
    XSS, CSRF 모두 취약
    HttpOnly 속성을 통해 script에서 접근 불가능하도록 처리 -> XSS 공격 방어
    SameSite 속성을 Strict 또는 Lax로 설정 -> CSRF 공격 방어

    • SameSite
      쿠키가 외부 사이트 요청에 자동으로 포함되지 않도록 설정
      • SameSite = Strict : 같은 사이트에서만 전송
      • SameSite = Lax : 외부사이트의 GET 요청에 대해서만 쿠키 전송
      • SameSite = None : 외부 사이트에서 요청 가능 (Secure 쿠키에 한해서)

결론: Cookie에 JWT를 저장하고, HttpOnly, secure, SameSite 옵션을 적용

JWT가 탈취 당한다면?

JWT가 탈취되면 서버는 탈취당한 사실을 알 수 없으므로 보안을 강화하기 위해 Access Token과 Refresh Token을 나누어 사용합니다.

  • Access Token의 유효기간을 짧게 설정해 토큰이 탈취돼도 금방 만료되도록 처리합니다.
  • 하지만 이는 사용자 측면에서 불편하므로, Refresh Token을 활용해 재발급 받을 수 있도록 합니다.

Refresh Token 까지 탈취당한다면?

  • Refresh Token Rotation을 활용하여 문제를 해결합니다.
  • Access Token을 재발급 받을 때 Refresh Token도 재발급됩니다.
    즉, Refresh Token을 일회용으로 사용하도록 구현합니다.

만약 탈취범이 먼저 재발급을 받아버린다면?

  • 토큰 탈취범이 정상 유저보다 먼저 재발급을 받으면, AT와 RT는 새로운 토큰으로 갱신되고, 저장소에는 탈취범의 Refresh Token만 남게 됩니다.
  • 정상 유저가 재발급을 받으면, Redis 서버에 탈취범의 RT만 남아 있기 때문에 정상 유저는 재발급을 받을 수 없습니다.
  • 정상 유저는 다시 로그인을 통해 Refresh Token을 발급받게 되며, 이로 인해 한 명의 사용자에 대해 여러 개의 Refresh Token이 생성됩니다.

Redis의 Key : Value 쌍을 RT : UserPK가 아닌 UserPk : RT로 설정하여 Redis 서버에 한 명의 사용자에 대해 하나의 토큰만 존재하도록 강제합니다.

참고 자료

  • JWT Introduction
  • JWT 관련 블로그
  • Tistory - JWT 보안
  • Tistory - JWT 탈취 방지
  • Tistory - JWT & Refresh Token
  • Tistory - JWT와 Refresh Token
저작자표시 비영리 변경금지

'Spring 단기심화 2기' 카테고리의 다른 글

TIL_저장 프로시저_241123  (1) 2024.11.23
TIL_Transaction_241122  (0) 2024.11.22
TIL_람다와스트림_241119  (0) 2024.11.19
TIL_Spring 예외 처리_241115  (2) 2024.11.15
TIL_MSA 들어가기_241114  (0) 2024.11.14
'Spring 단기심화 2기' 카테고리의 다른 글
  • TIL_저장 프로시저_241123
  • TIL_Transaction_241122
  • TIL_람다와스트림_241119
  • TIL_Spring 예외 처리_241115
l'avenirJun
l'avenirJun
  • l'avenirJun
    오늘도 꾸준히 개발
    l'avenirJun
  • 전체
    오늘
    어제
    • 분류 전체보기 N
      • 📚 개발자의 서재 N
        • 객체지향의 사실과 오해
        • Good Code, Bad Code
        • 도메인 주도 개발 시작하기 N
      • 🔧 트러블 슈팅
      • Java
      • Spring
      • 운영체제
        • 공룡책 학습
      • 알고리즘
      • GIT
      • 면접 지식
      • Spring 단기심화 2기
  • 블로그 메뉴

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

  • 공지사항

  • 인기 글

  • 태그

    DIP
    유스케이스
    specification
    매핑 구현
    가독성
    추상화
    타입
    모듈화
    코딩트리조별과제
    good code bad code
    객체지향의 사실과 오해
    티스토리챌린지
    책임-주도 설계
    애그리거트
    코드 계약
    리포지터리
    코딩테스트
    책임
    오블완
    일반화
    객체
    메시지
    애그리거트 루트
    도메인 모델
    캡슐화
    협력
    코드트리
    역할
    인터페이스
    도메인 주도 개발 시작하기
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
l'avenirJun
TIL_JWT_241121
상단으로

티스토리툴바