JWT

강한친구·2022년 8월 16일
0

Json Web Token

JWT는 웹 표준 (RFC 7519) 으로, 정보의 안정성 있는 전달을 목표로 한다.
따라서 다양한 개발언어에서 지원되고 있다.
JWT는 또한 자가 수용적이다.

자가 수용적 (self-contained)

자가 수용적이란 자신 스스로 모든 정보를 가지고있다는 의미이다. 토큰에 대한 정보, 전달할 정보, 검증 signature까지 모두 가지고 있다.

JWT의 구조

JWT는 .으로 구분되는 머리 가슴 배 Header, Payload, Signature로 구성되어있다. 아래의 예시는 jwt.io에서 제공하는 예시중 하나이다.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

첫번째 부분이 Header 부분이다.
헤더에는 두가지 정보가들어있다.
type: 토큰의 타입 (JWT)
alg: 해싱 알고리즘, 즉 서명이 무슨 알고리즘으로 되어있는지에 대한 정보이다.

예시의 헤더는 다음과 같은 정보를 담고있다.

{
  "alg": "HS256",
  "typ": "JWT"
}

JWT타입의 토큰을 HS256으로 암호화했다는 의미이다.

HS256은 HMAC SHA256 방식이다.

Payload

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ

페이로드 부분에는 토큰에 담을 정보가 들어간다. 여기에 담기는 정보 하나를 클레임이라 하고 클레임은 name : value 구조를 가진다.

이 클레임은 총 3가지 종류가 있다.

  1. registerd claim
    등록된 클레임은 서비스에 필요한 정보가 아닌, 이미 이름이 정해진 클레임들이다. 등록된 클레임은 사용하지 않아도 되며, 종류는 다음과 같다.
iss: 토큰 발급자 (issuer)
sub: 토큰 제목 (subject)
aud: 토큰 대상자 (audience)
exp: 토큰의 만료시간 (expiraton), 시간은 NumericDate 형식으로 되어있어야 하며 (예: 1480849147370) 언제나 현재 시간보다 이후로 설정되어있어야합니다.
nbf: Not Before 를 의미하며, 토큰의 활성 날짜와 비슷한 개념입니다. 여기에도 NumericDate 형식으로 날짜를 지정하며, 이 날짜가 지나기 전까지는 토큰이 처리되지 않습니다.
iat: 토큰이 발급된 시간 (issued at), 이 값을 사용하여 토큰의 age 가 얼마나 되었는지 판단 할 수 있습니다.
jti: JWT의 고유 식별자로서, 주로 중복적인 처리를 방지하기 위하여 사용됩니다. 일회용 토큰에 사용하면 유용합니다.

출처 ㅣ https://velopert.com/2389
  1. public claim
    공개 클레임은 충돌방지 이름을 가지고 있어야한다. 따라서 URI를 그 이름으로 가진다.
  1. Private Claim
    비공개 클레임은 서버와 클라이언트가 미리 스펙을 지정해서 사용하기로 한 클레임이다. 이름중복으로 인한 충돌위험이 있다.

예시로 주어진 JWT에서는 등록클레임, 비공개 클레임을 사용하며 다음과 같다.

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

제목, 이름, 그리고 발급시간을 가지고 있다. 로그인 환경에서는 여기에 exp를 넣는다.

Signature

SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

서명은 해당 토큰의 인정여부를 검증하기 위한 장치이다. 헤더의 인코딩값과 페이로드의 인코딩값을 합하고 서버의 비밀키로 해쉬하여 생성한다.

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  your-256-bit-secret
) 

이렇게 만들어진 해쉬를 미리 정해진 알고리즘으로 인코딩하면 그 값이 서명이 된다.

서버에서는 검증을 할 때 이 부분을 미리 저장된 시크릿과 알고리즘으로 뜯어서 확인해보고 검증하는 것이다.

예시에서는 'your-256-bit-secret' 이라는 비밀키로 암호화 서명을 하였다.

OsYeNeIRzSGp0Ss232RIL9xjKwsmo-c6slPSi0plpWE

시크릿을 Secret로 바꾸면 이렇게 변하게 된다.

이로써 JWT의 개념설명은 끝이다.
이를 활용하는 로그인에 대해 정리하면, 프로젝트에서 가장 골머리를 썩게 만들었던 로그인 부분에 대한 모든 정리가 끝난다.

0개의 댓글