Json Web Token

  • 사용자 인증 및 권한 부여에 널리 사용되는 토큰 기반 인증 방식이다.
  • 클라이언트와 서버 간에 정보를 안전하게 전달하기 위한 JSON 기반의 암호화된 토큰이다.
  • JWT는 세 파트로 나누어지며, 각 파트는 점(.)으로 구분하여 표현한다.

1) Header ( 헤더 ) : 해시 암호화 알고리즘과 토큰의 타입으로 구성

{
  "alg": "HS256",
  "typ": "JWT"
}
  • alg: 서명에 사용할 알고리즘 (예: HMAC SHA256)
  • typ: 토큰의 타입, 일반적으로 “JWT”

2) Payload ( 페이로드 ) : 내용, 즉 토큰에 담을 클레임(claim) 정보를 포함

{
  "sub": "user123",
  "name": "홍길동",
  "role": "USER",
  "exp": 1717032200
}
  • 실제 데이터(클레임)을 담고있는 부분

  • 주요 클레임 :

    1. iss(issuer) : 발행자
    2. exp(expiration time) : 만료시간
    3. sub(subject) : 제목
    4. iat(issued At) : 발행 시간
    5. jti(JWT ID) : 토큰의 고유 식별자
    6. 사용자 정의 클레임 ( 예 : role , email 등..)

3) Signature ( 서명 ) : 서명

HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)
  • 서명은 토큰의 위변조 여부를 검증하는 데 사용됨
  • 비밀 키(secret)를 사용해 생성
  • 서명을 통해 서버는 Token이 변조되지 않았음을 확인할 수 있다.

JWT 동작 방식

  1. 클라이언트의 로그인 요청
  2. 로그인에 성공했다면 Header, Payload에 Secret Key를 사용하여 Signature를 만든다
    • 이후 Base64로 Encoding한다
    • 일반적으로 Cookie에 담아 클라이언트에게 JWT를 발급한다.
  3. 발급받은 JWT를 저장 후 서버에 요청할 때 Authorization Header에 JWT를 담아 보낸다
  4. 서버에서 JWT의 유효성 검사를 통해 통과한다면 인증에 성공하여 요청을 처리해준다.
    • JWT 만료, 위변조 여부를 검사한다.

JWT의 유효성 검사

  1. A의 JWT를 B가 탈취
  2. B가 탈취한 JWT를 임의로 수정
  3. B가 수정한 JWT로 Server에 요청
  4. 서버는 Signature를 사용하여 유효성 검사(Signature 불일치)
    • Header, Payload를 서버의 Secret Key값을 이용해 Signature를 다시 만들어 비교한다.
    • 임의로 조작된 데이터를 판별할 수 있다.

JWT 장단점

  • 장점
    1. Signature로 서버의 보안성이 증가한다.
    2. Token 자체가 필요한 정보(유저 및 검증 정보)들을 모두 가지고 있다.
    3. 서버는 인증 정보와 관련된 별도의 저장소를 사용하지 않는다.
    4. 서버의 수평 확장성(Scale Out)이 높아진다.
    5. Cookie가 없는 다른 환경에서도 인증/인가를 적용할 수 있다.
    6. DB를 조회하지 않아도 된다.
  • 단점
    1. Payload는 암호화 된 것이 아니라 민감한 정보를 다루지 못한다.
    2. Token의 길이가 길어서 트래픽이 증가하면 네트워크에 부하가 증가한다.
    3. 클라이언트 측에서 Token을 관리하기 때문에 탈취당하면 대처하기 어렵다.

JWT vs Session

항목 JWT (JSON Web Token) Session (세션 기반 인증)
저장 위치 클라이언트 (주로 브라우저의 LocalStorage나 Cookie) 서버 (메모리, DB 등)
서버 상태 Stateless (무상태) Stateful (서버가 상태를 기억함)
확장성 높음 (서버 간 상태 공유 불필요) 낮음 (분산 서버에서는 세션 공유 필요)
속도 일반적으로 빠름 (DB 조회 없음) 느릴 수 있음 (세션 조회 필요)
무효화 어려움 (토큰 유효기간 동안 유효) 쉬움 (서버에서 세션 삭제)
보안 토큰이 탈취되면 만료 전까지 사용 가능 세션 ID 탈취 시 위험하지만 제어 가능
저장 용량 클라이언트에 모든 정보 포함 (무거울 수 있음) 서버에 정보 저장, 클라이언트는 세션ID만 보관
권한/정보 포함 포함 가능 (ex. role, email 등) 일반적으로 별도로 DB에서 조회
토큰 만료 처리 클라이언트 토큰 자체에 exp 내장 서버에서 세션 만료 시간 관리
사용 예 모바일/SPA/API 서버, 마이크로서비스 전통적인 웹 앱, 내부 시스템

JWT를 그럼 언제 사용할까?

  • 마이크로서비스 아키텍처 또는 서버리스 환경
  • API 서버 간 확장성이 중요할 때
  • 모바일 앱 또는 SPA(Single Page Application)에서 인증을 처리할 때
  • 세션 공유가 어려운 분산 시스템

Session은 언제?

  • 보안이 더 중요하고 서버 제어가 쉬운 환경
  • 사용자 수가 적고 단일 서버 또는 간단한 구조
  • 서버에서 인증 정보를 쉽게 무효화하거나 추적해야 할 때
  • 전통적인 웹 애플리케이션에서 로그인/로그아웃을 구현할 때

결론

상황 추천 방식
빠른 확장성과 API 중심의 서비스 JWT
간단한 시스템, 보안 중심 웹 서비스 Session

Token의 유형

  1. Access Token
    • 사용자 인증 후 서버가 발급하는 유저 정보가 담긴 토큰이다.
    • 유효 기간 동안 API나 리소스에 접근할 때 사용한다.
  2. Refresh Token
    • Access Token은 보안을 위해 짧은 수명을 가진다
    • Access Token이 만료된 경우 재발급 받기 위해 사용한다.
    • 주로 데이터베이스에 유저 정보와 같이 저장한다.

Access Token, Refresh Token 인증

  1. 클라이언트의 로그인 요청
  2. 로그인에 성공했다면 Header, Payload에 Secret Key를 사용하여 Signature를 만든다.
  3. 발급받은 JWT를 저장 후 서버에 요청할 때 Authorization Header에 JWT(Access Token)를 담아 보낸다.
  4. 서버에서 JWT의 유효성 검사를 통해 통과한다면 인증에 성공하여 요청을 처리해준다.
  5. Access Token이 만료 되었다면 Refresh Token 으로 토큰 재발급을 요청한다.
  6. 서버로부터 Access Token을 재발급 받는다.