JWT (JSON Web Token)
•
Json을 이용한 클레임 기반 토큰
◦
일반 토큰 기반
▪
의미없는 문자열 토큰
•
ex. 9ace025c90c0da2161075da6ddd3492a2fca776
▪
단점
•
발급한 토큰을 만료시킬 수단이 없고
•
토큰 검사할 때마다, DB에 접근하여 검사하는 것은 부담
◦
클레임 기반
▪
토큰에 name-value쌍의 클레임들이 정보로 담김
•
용도
◦
HTTP 통신 시 인증 및 권한부여를 위한 value값으로, Request 메시지 헤더에 담김
{
Authorization: Bearer 토큰
}
JSON
복사
•
구성
◦
. 을 구분자로 3가지 문자열로 구성됨
◦
헤더(Header).내용(Payload).서명(Signature)
◦
헤더
▪
토큰 타입과 해싱 알고리즘 정보 저장
{
"typ":"JWT",
"alg":"HS256"
}
JSON
복사
•
위의 Json이 Base64로 인코딩되어 JWT의 첫번째 부분을 구성
cf. Base64 인코딩 과정
•
알고리즘 정보는 토큰을 검증하는 Signature 부분에서 사용됨
◦
내용 (Payload)
▪
토큰에 담을 정보(클레임) 저장
// 페이로드 예시
{
"iss": "tandohak.co.kr", // 등록된 클레임
"exp": "1485270000000", // 등록된 클레임
"https://tandohak.co.kr/is_authenticated": true, // 공개 클레임
"username": "tandohak" // 비공개 클레임
}
JSON
복사
•
위의 Json이 Base64로 인코딩되어 JWT의 두번째 부분을 구성
▪
클레임 (Claim)
•
name-value 쌍으로 이루어짐
•
종류
◦
등록된 클레임 (Registered Claim)
▪
name이 이미 지정된 클레임
▪
서비스에 필요한 정보가 아니라, 토큰의 정보를 담음
▪
종류
•
iss : 토큰 발급자(issuser)
•
sub : 토큰 제목(subject)
•
aud : 토큰 대상자(audience)
•
exp : 토큰 만료시간
◦
공개 클레임 (Public Claim)
▪
사용자 정의 클레임
▪
등록된 클레임에 덧붙여 공개되어도 무방한 정보
▪
충돌(중복) 방지를 위해 uri 형식의 name을 가짐
•
공개 클레임은 공개 레지스트리에 저장되기 때문에 해당 클레임을 중복이 되면 중복된 클레임 중 어떤 것이 의도하고자 했던 클레임인지 파악 불가능
•
예. 현재 유저가 해당 서비스에 관리자 권한을 가졌는지 정보를 저장하는 클레임
{ "https://chup.tistory.com/jwt_claims/is_admin" : true }
JSON
복사
◦
비공개 클레임(Private Claim)
▪
사용자 정의 클레임
▪
공개하지 않는 정보
•
공개 클레임에는 이름, 이메일 등 일반 정보가 포함될 수 있지만, 비공개 클레임에는 직원ID과 같이 더 구체적인 정보 포함
▪
공개 레지스트리에 없기 때문에 name 중복가능
•
즉, 다른 서비스 토큰에서 중복되도 상관없는 name 사용
{
"userId": "dev-coco",
"username": "coco"
}
JSON
복사
◦
cf. 클레임을 공개나 비공개로 설정하는 방법
▪
공개 클레임 규칙을 준수하는 등록되지 않은 클레임 == 공개 클레임
▪
그렇지 않으면 == 비공개 클레임
◦
서명 (Signature)
▪
토큰의 변조여부를 검증하는 부분
▪
서명 부분 생성 방법
•
인코딩된 Header, 인코딩된 Payload, 비밀키, Header에 지정된 알고리즘 필요
⇒ Header의 인코딩값과 Payload의 인코딩값을 합친 후, 주어진 비밀키로 해시하여 생성
•
예. HMAC SHA256 알고리즘 사용할 때, 생성 방법
HMACSHA256(
base64UrlEncode(Header) + "." + base64UrlEncode(Payload)
, 비밀키)
JSON
복사
•
장점
◦
트래픽 줄일 수 있음
▪
토큰이 이미 필요한 정보를 갖고 있기 때문에, 세션과 달리 별도의 저장소 처리가 필요없어서
•
단점
◦
정보가 많아질 수록, 토큰 길이가 길어져 네트워크 부담
◦
페이로드는 암호화되서 보내지는 것이 아니라, base64로 인코딩된 것이기에, 공격자에 의해 디코딩 될 수 있음
▪
따라서 보안에 취약하기 때문에 중요한 데이터를 토큰에 저장해선 안되고, 토큰을 오래 보관해서도 안됨
◦
발급된 JWT는 삭제 불가능
▪
보완 방법
•
토큰 만료시간을 짧게 설정한 후, Refresh Token을 발급하여 토큰을 재발급할 수 있게 함
•
작동 과정/원리/순서
1.
클라이언트는 HTTP Request를 서버에 보냄
2.
서버는 유효한 클라이언트인지 확인 후, 토큰 발급
3.
토큰은 클라이언트의 브라우저에 저장
4.
클라이언트는 그 토큰을 HTTP Request Header 넣어 보내서 인증
◦
ex. 엑세스 토큰 발급 과정