HTTP/WEB : JWT(JSON Web Token)

은경·2022년 2월 8일
0

[WEB/HTTP]

목록 보기
5/7

1. JWT(JSON Web Token) 이란?


JWT란 JSON 포맷을 이용해 사용자에 대한 속성(claim)을 저장하는 Web Token

토큰 자체를 정보로 사용하는 Self-Contained 방식으로 정보를 안전하게 전달.
주로 회원 인증에 사용된다.


2. JWT의 구성


  • Header, Payload, Signature 세 부분으로 구성
  • 각 부분은 "." (마침표)를 통해서 연결, Base64로 인코딩 됨
  • HeaderPayloadJSON 기반의 Key-value 형태로 구성됨
  • Signature는 Header와 Payload를 기반으로 생성된다.

  • 토큰의 타입을 나타내는 typ key
  • 해시 암호화 알고리즘(SHA256,RSA 등)을 나타내는 alg key로 구성.

PayLoad

  • 토큰에 담을 Claim 정보 포함, 페이로드에 담는 정보의 한 '조각'을 클레임 이라고 함. (토큰에 여러개의 클레임들을 넣을 수 있음)

  • 이는 key/value의 한 쌍으로 이루어져 있다.

  • Claim은 총 3가지로 나눌 수 있다.

    • 등록된 클레임(Registered Claim)

      토큰 정보를 표현하기 위해 이미 정해진 종류의 데이터들
      모두 선택적으로 작성이 가능하며 사용할 것을 권장

      iss 토큰 발급자(issuer)
      sub 토큰 제목(subject) 주로 유니크한 값 사용(e-mail)
      aud 토큰 대상자(audience)
      exp 토큰 만료 시간(expiration), NumericDate 형식으로 되어 있어야 함 ex) 1480849147370
      nbf 토큰 활성 날짜(not before), 이 날이 지나기 전의 토큰은 활성화되지 않음
      iat 토큰 발급 시간(issued at), 토큰 발급 이후의 경과 시간을 알 수 있음
      jti JWT 토큰 식별자(JWT ID), 중복 방지를 위해 사용하며, 일회용 토큰(Access Token) 등에 사용
      출처 : https://mangkyu.tistory.com/56

    • 공개 클레임(Public Claim)

      토큰이 전달하려는 실제 데이터, 사용자 정의 클레임
      모두에게 공개된 공개된 정보를 위해 사용 (URI포맷 이용)

    • 비공개 클레임(Private Claim)

      사용자 정의 클레임
      서버와 클라이언트 사이에 임의로 지정한 정보를 저장.

Signature

  • 서명(Signature)은 토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호화 코드
  • 위의 헤더와 페이로드 값을 BASE64로 인코딩 후 값을 비밀 키를 이용해 헤더에서 정의한 알고리즘으로 해싱하고 이 값을 다시 BASE64로 인코딩 하여 생성.
JWT의 Header와 Payload는 Base64로 Encoding 되어 있기 때문에 누구든지 JWT의 Header와 
Payload를 Decoding하여 확인할 수 있고, JWT를 가로채어 기존의 Payload를 조작된 Payload와
교체하는 일도 어렵지 않다. JWT에서는 이러한 보안 문제를 해결하기 위해서 Signature를 이용한다. 
Signature를 통해서 Header와 Payload가 조작되지 않았으며, 인증된 App으로부터 전송 되었다는걸 
검증할 수 있다.
Signature는 Base64로 Encoding된 Header와 Payload를 "." (마침표)로 연결한 
문자열과 사용자가 임의로 설정한 Password (대칭키, 비대칭키)를 이용하여 암호화 한다음,
다시 Base64로 Encoding하여 생성한다. JWT를 수신한 App은 수신한 JWT의 Header,
Payload 및 자신이 알고 있는 Password를 이용하여 Signature를 생성한 다음, 
수신한 JWT의 Signature와 비교한다. 만약 두 Signature가 동일하다면 해당 JWT는 유효하다는 의미.

출처 : https://ssup2.github.io/theory_analysis/JWT/

생성된 토큰은 HTTP 통신 시 Authorization이라는 key의 value로 사용됨. value에는 Bearer이 앞에 붙여진다.

{ 
    "Authorization": "Bearer {생성된 토큰 값}",
 }

access token과 refresh token

로그인을 하고 인증됐을 경우 서버에서 Secret Key를 사용해서 발급하는 토큰이다.

  • access token
    • 사용자가 서버에 요청을 보낼때 헤더에 함께 보내는 접근용 토큰
    • 만료 기간이 10분 정도로 짧음
    • 도난 당해도 금방 만료되므로 안전함
  • refresh token
    • access token이 만료되었을 때 재발급받기 위한 인증용 토큰
    • 평소 요청엔 포함되지 않음
    • 만료기간은 자동로그인 기능을 몇달로 지정할지에 따라 조절 가능
    • 만료되면 사용자에게 다시 로그인 요청

3. JWT 작동 원리


 1. 사용자가 로그인을 요청하고 id, pw 정보가 유효하다면, 서버에서 Secret Key를 사용해서 
    JWT(access token, refresh token)을 발급한다.
 2. 서버에서 JWT를 브라우저로 전달한다. 이때, 사용자의 local storage에 
    JWT(access token, refresh token)를 저장한다.
 3. 브라우저는 모든 request의 헤더에 access token을 함께 전송한다.
 4. 서버는 브라우저가 보낸 access token을 식별하고 유효하다면, 원하는 응답을 제공해준다.

4. 특징


  • JWT처럼 자신에게 필요한 모든 정보를 담고 있는 특징을 Self-contained라고 표현한다

  • 서버는 클라이언트의 정보를 저장하지 않고, JWT의 발급과 매 요청마다 header에 넘어오는 access token의 유효성 검사만 진행한다.

  • 서버가 클라이언트의 정보를 저장하지 않으므로 Stateless 서버이다.

  • 클라이언트 측에서 관리해야 하기 때문에, 로컬 스토리지에 토큰을 저장해야 한다.

  • 페이로드(Payload) 자체는 암호화 된 것이 아니라, BASE64로 인코딩 된 것이기 때문에 중요한 정보는 넣으면 안된다.

장점

  1. 클라이언트에 저장 -> 서버 메모리, DB에 부담이 없다.
  2. 로드밸런싱을 사용한 서버 확장에 유리함.
  3. 엑세스 토큰의 만료기간이 짧아 도난 당해도 안전성이 높음.
  4. CORS방식을 사용하기 용이함.
  5. 멀티 디바이스 환경에서 부담이 없음.

단점

  1. 서버에 클라이언트 상태가 저장되어 있지 않아서, 사용자의 로그인 여부 확인, 강제로그아웃 등의 제재를 가하기 힘듬.
  2. 클라이언트가 임의로 토큰 수정,구조변경시 서버에서 확인불가->세션방식에 비해 상대적으로 안정성이 낮음
  3. 리프레쉬 토큰이 도난됐을 경우 엑세스 토큰을 계속 발급받으며 악용 가능
  4. Payload 부분에 사용자의 필요한 모든 정보를 저장하는 경우가 많아 Session Id의 길이보다 길다. (즉, HTTP request가 무거워질 수 있다.)
  5. 따라서 토큰이 길어질 경우 DB에 부하가 걸릴 수 있음.



참고 자료 (Reference)


https://surprisecomputer.tistory.com/37
https://mangkyu.tistory.com/56
https://ssup2.github.io/theory_analysis/JWT/
https://blog.makerjun.com/a71d6925-05a0-4b46-840f-72f719d90a93

profile
Python 서버 개발자

0개의 댓글