JWT(Json Web Token)

HunkiKim·2022년 9월 9일
0

JWT(Json Web Token)

  • Json 포맷을 이용하여 사용자에 대한 속성을 저장하는 Claim 기반의 Web Token

    Claim이란 사용자 정보나 데이터 속성을 의미
    클레임 기반 토큰이란 정보를 담은 토큰이다.
    즉 사용자 정보나 데이터 속성을 담은 토큰이다.

  • 토큰 자체를 정보로 사용 -> Self-Contained 방식
  • 거의 대부분 주류 프로그래밍 언어에서 지원된다.
    • C,Java,Python, C++,R,C#,PHP,JavaScript,Ruby,Go,Swift
    • Request header, URL의 파라미터 등으로 전달 가능함 (손쉽게 전달 가능, 자가수용적)

사용

  • 회원 인증 : 쿠키와 비슷하게 사용
  • 정보 교루 : 정보가 sign 되어 있기 때문에, 조작 되었는지 검증 가능

구성

  • 헤더, 페이로드, 서명으로 구성
  • 각 구분은 . 구분자로 나누어 표현
  • 각 값은 BASE64로 인코딩된 형태
    • aaaaa.bbbbb.cccccc
    • 헤더(header).내용(payload).서명(signature)
  • 헤더
{
"typ" : "JWT",
"alg" : "HS512"
}
  • typ : 토큰의 타입을 지정(jwt)
  • alg : 해싱 알고리즘을 지정
    • 주로 HMAC SHA256 또는 RSA를 사용
    • 서명(Signature)에서 이 알고리즘을 사용
  • 즉 header에는 보통 토큰의 타입이나, 서명 생성에 어떤 알고리즘이 사용되었는지 저장한다. 위의 예시는 토큰의 타입이 JWT이고, 개인키로 HS512 알고리즘이 적용되어 암호와가 되어있다.
  • 페이로드
    • 토큰에서 사용할 정보가 담긴, 즉 클레임이 저장되어 있다.
    • Claim은 토큰에서 사용할 정보의 조각이다.
    • key-value쌍으로 저장한다.
    • 여러 개의 정보 저장 가능하다.
{
    "sub" : "1234"
    "name" : "Hunki Kim"
    "iat" : 123543
}
  • 클레임의 세 가지 종류
    • 등록된 클레임 : 토큰에 대한 정보를 담기 위해 이름이 정해진 클레임이다. iss(토큰 발급자), sub(토큰 제목), aud(토큰 대상자), exp(토큰의 만료시간), nbf(토큰 활성 날짜), iat(토큰 발급 시간), jti(JWT 토큰 식별자)
    • 공개 클레임 : 충돌이 방지된 이름으로 URL 형식의 이름이다. "https://velopert.com/jwt_claims/is_admin" : true
    • 비공개 클레임 : 클라이언트와 서버의 협의하에 사용되는 이름, 이름이 중보되어 충돌 될 수 있음
  • 표준 스펙상 key의 이름은 3글자로 되어있습니다. JWT의 핵심 목표는 사용자에 대한, 토큰에 대한 표현을 압축하는 것이라고 볼 수 있다. 상황에 따라 해당 서버가 가져아 할 인증 체계에 따라 등록된 클레임을 사용하면 된다.
    가장 중요한 것은 payload에 민감한 정보는 담지 않는 것이다. header와 payload는 json이 인코딩되어있을 뿐이지 특별한 암호화가 걸려있는 것이 아니기 때문에 jwt를 가지고 코딩하면 header와 payload에 담긴 값을 알 수 잇다. 그래서 JWT는 단순히 식별을 하기 위한 정보만을 담아두어야 한다.

header와 payload를 암호화 하면 되지 않냐고 할 수 있다. 예를 들어 base64UrlEncode로 암호화 하는방식이 있을 수 잇다. 하지만 그 자체로 많은 리소스를 사용한다. http 요청마다 한 번의 복호화가 추가되기 때문이다. 따라서 민감하지 않은 정보인 header와 payload를 암호화 할 필요는 없다.

  • 서명
    • Header와 Payload를 BASE64로 인코딩한 값을 합친 후 인코딩한 값을 합친 후 비밀키로 해쉬를 하여 생성
    • 해시 알고리즘은 header에 정한 것으로 사용
    • base64형태로 나타낸다 (hex -> base64)

HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEoncode(payload),
your-256-bit-secret
) secret base64 encoded
your-256-bit-secret은 서버가 가지고 있는 개인키이다. 따라서 서명은 서버에 있는 개인키로만 암호화를 풀 수 있으므로 다른 클라이언트는 임의로 Signature를 복호화할 수 없다.

장점

  • 별도의 세션 저장소 관리를 필요로 하는 세션/쿠키 방식에 비해 간편
    • 토큰 자체에 정보가 포함되어 있음
    • JWT는 유효성과 sign을 이용하여 조작 여부만 검증하고 사용
  • 확장성이 뛰어나다. (클라이언트 단에 저장되며 stateless하기 때문)
    • 토큰을 기반으로 인증하는 다른 인증 시스템(Google 로그인, Facebook 로그인 등)에 접근 가능

단점

  • 페이로드에 담긴 정보는 암호화 되지 않아 중요한 데이터를 넣으면 안된다.
    • 유효기간을 짧게 만들고 refresh token 추가
  • 페이로드의 크기가 커지면, 토큰의 길이가 길어져 네트워크에 부하를 줄 수 있음
  • 토큰 기반 시스템은 Stateless하다. JWT는 상태를 저장하지 않기 때문에 한 번 만들어지면 제어가 불가능하다.
    • 즉, 토큰 임의 삭제가 불가능함으로 토큰 만료시간을 포함해야 한다.
    • 그렇기 때문에 Access Token의 유효기간을 짧게 만들고, Refresh Token을 새로 발급

자세한 사진은 노션에서 확인.

JWT와 OAuth의 차이

간단하게 OAuth는 다른 웹 서비스의 계정으로 사용자 인증을 대신하는 기술이다. 자세한 내용은 아래 참고.
https://victorydntmd.tistory.com/4

OAuth Token

  • 사용자 정보를 가진 토큰이 아니다. (모호한 토큰)
  • pointer와 같은 랜덤 문자열 정보를 가진다.
  • 정보가 저장되어 있는 위치에 대한 포인터를 가진다.
  • 토큰 자체에 정보가 저장되어 있는 JWT와 다르다.

0개의 댓글