[Blazor] JWT

참고


JWT란

  • JWT(JSON Web Token)는 일반적으로 클라이언트(App FrontEnd) 와 서버 (App BackEnd) 간에 정보를 공유하는 데 사용되는 개방형 산업 표준입니다.
  • JWT 는 Token 자체를 정보로 사용하는 Self-Contained 방식이며, 필요한 모든 정보를 Token에 저장하기 때문에 서버와의 커뮤니케이션에서 오버헤드를 최소화 할 수 있습니다.
  • 또한 JSON Content(JWT Claim) 을 변경 할 수 없도록 암호화 되어 있습니다.
  • 아래는 Google 에 로그인하면 Claim/JSON Payload 가 포함된 JWT 를 방생하는 내용입니다.
{
    "iss": "https://accounts.google.com",
    "azp": "1234987819200.apps.googleusercontent.com",
    "aud": "1234987819200.apps.googleusercontent.com",
    "sub": "10769150350006150715113082367",
    "at_hash": "HK6E_P6Dh8Y93mRNtsDB1Q",
    "email": "jsmith@example.com",
    "email_verified": "true",
    "iat": 1353601026,
    "exp": 1353604926,
    "nonce": "0394852-3190485-2490358",
    "hd": "example.com"
}

JWT 구조

  • Header : Token 유형에 대한 메타데이터와 해당 콘텐츠를 보호하는 데 사용되는 암호화 알고리즘을 포함합니다.

  • Payload(Claim Set) : 사용자의 ID 및 허용 된 권한과 같은 검증 가능한 보안 설명이 포함되어 있습니다.

  • Signature : Json Payload 의 무결성을 확인하는 데 사용할 수 있는 암호화 알고리즘을 통해 생성 된 문자열입니다.

  • JWT Debugger 사이트에서 JWT 내용을 확인할 수 있습니다.


Header

{
    "alg": "HS256",
    "type": "JWT"
}
  • alg : 서명 암호화 암고리즘(ex: HMAC SHA256, RSA)
  • type : 토큰 유형
[JSON 객체]
Base64URLSafe(UTF-8('{"alg": "HS256","type": "JWT"}'))

[직렬화]
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

Payload

  • Payload 에는 엔티티(일반적인 사용자 정보) 에 대한 설명과 Claim 이라고 하는 추가 엔티티 속성이 포함됩니다.
  • 아래 속성들을 Claim Set 이라 부릅니다.
    • Claim Set
      • JWT에 대한 내용
      • 클라이언트와 서버 간 주고 받기로 한 값들로 구성
{
    "sub": "1234567890",
    "name": "John Doe",
    "admin": true
}
  • 페이로드는 정해진 데이터 타입은 없지만, 대표적으로 Registered claims, Public claims, Private claims 이렇게 3가지로 나뉩니다.
    • Registered claims : 미리 정의된 클레임
      • iss(issuer; 발행자)
      • exp(expireation time; 만료 시간)
      • sub(subject; 제목)
      • iat(issued At; 발행 시간)
      • jti(JWI ID)
    • public claims : 사용자가 정의할 수 있는 클레임 공개용 정보 전달을 위해 사용
    • private claims : 해당하는 당사자들 간에 정보를 공유하기 위해 만들어진 사용자 지정 클레임. 외부에 공개되도 상관 없지만 해당 유저를 특정할 수 있는 정보들을 담는다.
[JSON 객체]
Base64URLSafe(UTF-8('{"sub": "1234567890","name": "John Doe","admin": true}'))

[직렬화]
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ

key-value 형식으로 이루어진 한 쌍의 정보를 Claim 이라고 합니다.


Signature

  • 서명에서 사용하는 알고리즘은 Header 에서 정의한 알고리즘 방식(alg) 을 활용합니다.
  • 서명은 JWT를 보낸 사람이 누구인지 확인하고 메시지가 도중에 변경되지 않았는지 체크하는데 사용됩니다.
[Signature]

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

[직렬화]
tM-nO0TjFp-sF0-TYWjXKX_r9jEZvO1YWjKnWfIDWtM

JWT 인증 과정

  1. 사용자가 ID, PW 를 입력하여 서버에 로그인 인증을 요청합니다.
  2. 서버에서 클라이언트로부터 인증 요청을 받으면, Header, PayLoad, Signature 를 정의합니다. Header, PayLoad, Signature 를 각 Base64로 한 번 더 암호화하여 JWT를 생성하고 이를 쿠키에 담아 클라이언트에게 발급합니다.
  3. 클라이언트는 서버로부터 받은 JWT를 로컬 스토리지에 저장합니다. (쿠키나 다른 곳에 저장할 수도 있음) API를 서버에 요청할 때 Authorization header 에 Access Token 을 담아서 보냅니다.
  4. 서버가 할 일은 클라이언트가 Header 에 담아서 보낸 JWT 가 내 서버에서 발행한 토큰인지 일치 여부를 확인하여 일치한다면 인등을 통과시켜주고 아니면 통과시키지 않으면 됩니다. 인증이 통과되었으므로 PayLoad 에 들어있는 유저 정보들을 select 해서 클라이언트에게 돌려줍니다.
  5. 클라이언트가 서버에 요청을 했는데, 만일 액세스 토큰의 시간이 만료되면 클라이언트는 리프레시 토큰을 이용합니다.
  6. 서버는 새로운 액세스 토큰을 발급 받습니다.
728x90

이 글을 공유하기

댓글

Designed by JB FACTORY