JWT(JSON Web Token)와 같은 토큰은 자체 포함된 토큰(self-contained token)이다. 토큰 자체에 인증 및 인가 정보를 포함하고 있어서 별도의 서버 저장소를 참조하지 않고도 필요한 정보를 검증할 수 있다.
JWT의 구조
JWT는 세 부분으로 구성된 토큰이다.
- Header (헤더)
- Payload (페이로드)
- Signature (서명)
세 부분은 각각 Base64Url로 인코딩되며, 마침내 점(.)으로 구분되어 하나의 문자열로 결합된다.
1. Header (헤더)
헤더는 토큰의 타입과 사용된 서명 알고리즘을 지정한다.
{
"alg": "HS256",
"typ": "JWT"
}
2. Payload (페이로드)
페이로드는 클레임(claims)이라고 불리는 JSON 객체를 포함한다. 클레임은 토큰에 포함된 정보로, Registered, Public, Private claims가 있다.
- Registered claims: 토큰의 표준 필드(e.g., iss: issuer, sub: subject, exp: expiration time).
- Public claims: 공개된 정보로, 표준이 아닌 필드.
- Private claims: 특정 응용 프로그램 간에 정의된 정보.
{
"sub": "1234567890",
"name": "John Doe",
"admin": true,
"iat": 1516239022
}
3. Signature (서명)
서명은 헤더와 페이로드를 합친 후 비밀 키를 사용하여 생성된 해시 값. 해시 값으로 토큰의 무결성을 검증할 수 있다.
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
JWT의 보안 정보
JWT는 보안 정보를 자체적으로 포함하고 있는 정보는 페이로드와 서명을 통해 토큰의 진위 여부를 확인할 수 있다. 서버는 JWT의 서명을 확인하여 토큰이 변조되지 않았음을 검증할 수 있다. 또한, 페이로드에 포함된 정보(사용자 ID, 권한 등)를 통해 추가적인 데이터베이스 조회 없이 인증 및 인가를 수행할 수 있다.
보안 특징
- 기밀성: JWT는 기본적으로 인코딩만 되어 있고, 암호화되지 않은 경우 누구나 내용을 볼 수 있다. 민감한 정보는 JWT에 직접 포함하지 않고, 필요할 경우 암호화된 JWT(JWE, JSON Web Encryption)를 사용한다.
- 무결성: 서명을 통해 JWT의 무결성을 확인할 수 있다. 서명은 비밀 키 또는 공개/비공개 키 쌍을 사용하여 생성된다.
- 만료 시간: JWT에는 만료 시간(exp) 필드를 포함하여 토큰의 유효 기간을 지정할 수 있다. 토큰의 유효 기간은 오래된 토큰의 사용을 방지한다.
예시
클라이언트가 서버에 인증을 요청하면 서버는 JWT를 생성하여 클라이언트에 전달한다. 이후 클라이언트는 이 JWT를 사용하여 서버에 요청을 보낸다. 서버는 JWT의 서명을 검증하고 페이로드에 포함된 정보를 사용하여 요청을 처리한다.
Authorization: Bearer <token>
서버는 JWT의 유효성을 검증하기 위해 데이터베이스나 추가적인 저장소를 참조할 필요 없이 토큰 자체를 검증한다. 토큰 자체 검증은 서버의 부하를 줄이고 응답 시간을 개선할 수 있다.
따라서 JWT와 같은 자체 포함된 토큰은 인증 및 인가 과정을 단순화하고, 효율적으로 처리할 수 있는 장점이 있지만 민감한 정보의 보호를 위해 적절한 암호화와 보안 설정이 필요하다.