JWT
JWT에 대해 학습했던 내용들을 정리하고자 한다.
JWT
JWT(Json Web Token)은 Json 형태의 토큰으로, 디지털 서명이 포함되어 있어 데이터가 위조되지 않았음을 보장할 수 있다. 개방형 표준(RFC-7519)이다.
개방형 표준: 기술 표준이 문서가 공개되어 있으며 사용이 자유로운 경우를 가리키는 용어
JWT는
- 서버가 세션을 관리할 필요가 없다.
- 무상태이기 때문에 토큰을 저장하지 않아도 된다.
- 인증 및 인가를 위해 요청이 올 때마다 토큰을 검증해 인증을 처리한다.
- 확장성이 뛰어난 시스템을 구축할 수 있다.
JWT 구조
JWT는 세 부분(헤더(header), 페이로드(payload), 서명(signature))으로 나뉜다.
형태는 xxxxx.yyyyy.zzzzz로, dot(.)으로 세 부분을 구분한다.
예시는 아래와 같다.
각각에 대해 알아보자.
1. 헤더(Header)
헤더는 일반적으로 토큰의 유형(JWT)과 사용된 암호화 알고리즘(HMAC SHA256 or RSA)을 담는다.
{
"alg": "HS256",
"typ": "JWT"
}
해당 내용은 Base64Url로 인코딩 되어 xxxxx 부분을 형성한다.
2. 페이로드(Payload)
실제 클레임(Claim) 데이터를 담고 있다.
Claim이란?
Payload에 포함된 데이터로, 토큰에 포함된 데이터 항목을 의미한다.
사용자 혹은 시스템에 대한 정보가 담긴다.
클레임 종류
1. 등록된 클레임(Registered Claims): JWT 표준에서 권장하는 클레임
- iss(issuer): 발행자
- sub(subject): 토큰의 주제
- aud(audience): 대상자
- exp(expiration): 만료 시간
- iat(issued at): 발행 시간
- nbf(not before): 사용할 수 있는 시간
2. 공개 클레임(Public Claims): 사용자가 정의할 수 있는 클레임. 충돌을 방지하기 위해 URI 등을 사용
3. 비공개 클레임(Private Claims): Application 내에서 특정 목적을 위해 정의한 클레임
Payload의 예시는 아래와 같다.
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
해당 내용도 header처럼 Base64Url로 인코딩해 yyyyy 부분을 형성한다.
이때 주의할 점은, JWT의 Header와 JWT는 복호화할 수 있기 때문에 암호화하지 않은 채 비밀 정보를 담지 말아야 한다는 것이다.
3. 서명(Signature)
JWT가 조작되지 않았음을 보장하기 위해 인코딩된 Header와 Payload, Secret, 헤더에 지정된 알고리즘(alg)을 활용해 생성한다.
예를 들어 HMAC SHA256 알고리즘을 사용했다면 아래와 같이 생성된다.
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
Token의 무결성을 보장하기 위한 장치이다.
JWT 저장
사용자 인증에 성공하면 JWT를 반환한다. 이후, 인증 및 인가를 하기 위한 자격 증명으로 사용되므로 저장을 주의해야 한다. JWT는 클라이언트 측에 저장한다.
클라이언트 측 JWT 저장 방법
- LocalStorage에 저장
장점: 편리하다.
단점: XSS 공격에 취약하다. - SessionStorage에 저장
위와 동일 - Cookie에 저장
장점: JS로 접근이 불가능하다. 따라서 XSS 공격에 취약하지 않다.
단점: CSRF 공격
결론: 어디에 저장하는 것이 좋은지에 대해 확정된 것은 없지만, 대부분의 경우 Cookie에 저장하고 CSRF 공격을 방지하는 것을 추천한다.
JWT 동작
JWT의 형태에 대해 알아보았으니, 이제 JWT를 활용한 동작 과정에 대해 살펴보자.
사용자가 인증에 성공해 JWT를 획득하면, 이후 API 요청 헤더에 아래 정보를 담는다.
Authorization: Bearer <token>
Authorization은 Http Request Header에 담기는 정보이며, 이후의 value에 JWT 정보가 담긴다.
Bearer는 '소유자'라는 의미이며, “이 토큰의 소유자에게 권한을 부여해 줘”라는 의미라고 한다.
자세한 정보는 아래 Toss 개발자 센터에서 확인할 수 있다.
https://docs.tosspayments.com/resources/glossary/bearer-auth
Bearer 인증 | 토스페이먼츠 개발자센터
Bearer 인증은 OAuth 2.0 프레임워크에서 사용하는 토큰 인증 방식이에요. “Bearer”은 소유자라는 뜻인데, “이 토큰의 소유자에게 권한을 부여해줘”라는 의미로 이름을 붙였다고 해요.
docs.tosspayments.com
Server 측에선 JWT의 Signature를 확인해 올바른 token인지 확인한다.
인증에 성공하면 Payload 정보 등으로 사용자를 특정한 후, 알맞은 API를 반환한다.