안녕하세요, 주니어 개발자 Eon입니다.
오늘 다룰 내용은 JWT (Json Web Token)입니다.
사용하는 / 사용되는 로직은 다음 포스트에서 다루겠습니다.
토큰 관련된 인증은 대부분 로그인할 때 사용됩니다.
그 중에서도 JWT는 웹 표준을 따르고 있으며, JSON 객체를 사용하여 정보를 전달합니다.
그리고, 필요한 모든 정보를 한 객체에 담아서 전달하기 때문에 JWT 한 가지로 인증을 마칠 수 있습니다.
(물론 보안에 좀 더 신경쓰겠다고 하면 여러 방어 기술들을 함께 쓸 수 있습니다.)
JWT의 장점 중 하나로, 웹 표준을 따르기 때문에 대부분의 언어가 이를 지원합니다.
사용처는 사용하기 나름이나, 앞서 소개한 것과 같이 '로그인' 과정에 쓰일 때 위주로 소개하겠습니다.
JWT의 구조
위와 같이 헤더, 내용, 서명이 '.(dot)'을 구분자로 하여 JWT 토큰 1개를 이룹니다.
완성된 토큰은 다음의 형태를 가집니다.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
위의 링크로 접속하면 JWT을 만들어볼 수 있습니다.
JSON은 Key, Value가 한 쌍을 이루는 객체를 말합니다.
https://www.w3schools.com/whatis/whatis_json.asp
{
"employees":[
{"firstName":"John", "lastName":"Doe"},
{"firstName":"Anna", "lastName":"Smith"},
{"firstName":"Peter", "lastName":"Jones"}
]
}
위와 같이, employees 라는 Key 값에 Value로써 3개의 array records가 들어있는 형태입니다.
물론 Value로 array가 아닌 "name"과 같이 단순한 string 하나로 구성될 수도 있습니다.
JWT에서는 원래 "name": "value"로써, "Key": "Value"라고 하지 않습니다.
하지만 편의를 위해 "Key": "Value"로 사용하겠습니다.
인코딩 : Base64
{
"alg": "HS256",
"typ": "JWT"
}
헤더에서는 해시 알고리즘과 토큰의 타입을 정의할 수 있습니다.
HS256은 HMAC SHA 256을 의미합니다.
해시 알고리즘 중 한 가지입니다.
타입의 값 JWT는 이 토큰을 JWT로 지정합니다.
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
내용에서는 전달하는 데이터를 포함할 수 있습니다.
데이터 각각의 Key를 claim이라고 부릅니다.
claim은 사용자가 원하는 Key와 Value로 구성할 수 있습니다.
claim에는 3가지 종류가 있습니다.
registered, public, private
컴팩트하게 3글자로 정의하며, 필수는 아니나 사용이 권장됩니다.
iss (issuer), exp (expiration time), sub (subject), aud (audience)
등이 있습니다.
그 외의 클레임 종류 : https://datatracker.ietf.org/doc/html/rfc7519#section-4.1
사용자가 자유롭게 정의할 수 있습니다.
단, 충돌을 방지하려면 IANA JSON 웹 토큰 레지스트리에 정의돼 있거나 충돌이 방지된 네임스페이스를 포함하는 URI로 정의해야 합니다.
URI로 정의하는 경우 :
{"http(s)://specific.uri/@unique_recommended_namespace/additional_path": true}
IANA JSON Web Token Registries : https://www.iana.org/assignments/jwt/jwt.xhtml
이는 등록된 또는 공개 클레임이 아닌 클레임이며, 정보를 공유하기 위해 만들어진 커스터마이징된 클레임입니다.
Payload는 서명된 파트가 아닙니다.
단순 Base64 인코딩이 된 파트이며, 이는 누구나 디코딩하여 데이터 열람이 가능합니다.
password 같은 결정적인 요소들은 Payload에 담기면 안 됩니다.
해시 : HMAC SHA 256
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
서명 파트는 위와 같이 Base64 인코딩된 Header "." Payload 그리고 secret이 필요합니다.
secret은 말 그대로 유저가 지정하는 비밀 코드입니다.
위와 같이 해싱하면 서명이 완성됩니다.
완성된 JWT는 이미 상단에 토큰의 형태로써 소개했습니다.
다음 포스팅에서는 JWT를 사용되는 플로우를 살펴보겠습니다.👍
좋은 글 감사합니다.