면접에서 받았던 질문이였는데 사실 대답은 제대로 못했다.
음 뭔가 좀 본능적이라고 해야될까? 개발을 하면서 흐름이나 어떤 역할을 하는지는 알고 있는데 용어를 정리하면서 설명을 하기가 막막해서 이참에 제대로 알아보는 시간을 가져야겠다고 생각했음.
실제 프로젝트를 진행하면서 성공적으로 구현을 해낸 기술에 대해서 제대로 설명을 못한 것이 아쉬웠다.
여튼 JWT 구조. 파보자.
난 JWT가 단순하게 헤더에 서명을 태워 보내서 사용자를 인증하기 위한 것으로만 알고 있었고 JWT 토큰에는 사용자의 정보가 암호화되어서 담겨있다는 것 정도만 인지하고 있었다. (사실 이거면 사용하는데에는 문제는 없다고 생각하고 있었다..)
정리를 해보자.
JWT는 Json Web Token의 약자이다. 사용자를 식별, 인증을 동시에 처리할 수 있는 토큰 기반의 인증 형식.
토큰 자체에 사용자의 식별 요소가 포함되어있음.
RESTful과 같이 Stateless(무상태) 환경에서 사용자 데이터를 주고 받는 것이 가능
-> 사용자와 백엔드의 통신을 최소화 할 수 있음을 뜻함. 왜? 토큰 자체에 식별 요소가 있으니까.토큰을 클라이언트에 저장하고, HTTP 헤더에 토큰을 포함시켜서 요청하는 것만으로 데이터 요청과 응답을 받을 수 있음.
정도가 되겠다.
내가 대답을 못했던 질문인데,

이미지를 보면 세개로 나눌 수 있다.
Header 예시.
{
"kid": "abc123", // 키 식별자
"typ": "JWT", // 토큰 타입
"alg": "HS256" // 서명 알고리즘
}
Registered Claims(등록된 클레임), Public Claims(공개 클레임), Private Cliams(비공개 클레임)로 구분됨.Registered Claims(등록된 클레임)iss (Issuer): 토큰 발급자sub (Subject): 토큰의 대상 (사용자 ID 등)aud (Audience): 토큰의 수신자exp (Expiration): 토큰 만료 시간iat (Issued At): 토큰 발급 시간nbf (Not Before): 토큰 활성화 시작 시간Public Claims (공개 클레임)Private Claims (비공개 클레임)Payload 예시
{
"sub": "123123", // 사용자 ID
"name": "철수", // 사용자 이름
"admin": false, // 관리자 여부
"exp": 720000 // 만료 시간
}
Header와 Payload 결합
Base64Url로 인코딩된 Header와 Payload를 .으로 연결.base64UrlEncode(Header) + "." + base64UrlEncode(Payload)서버에 저장된 비밀 키(key)와 Header에서 정의한 암호화 알고리즘(alg)을 사용해 위 데이터를 암호화.
일반적인 알고리즘:
- HS256 (HMAC + SHA-256): 대칭 키 방식
- RS256 (RSA + SHA-256): 비대칭 키 방식
Signature = HMACSHA256(
base64UrlEncode(Header) + "." + base64UrlEncode(Payload),
secretKey
)
Header, Payload, Signature를 .으로 연결한 최종 JWT가 생성.
<Header>.<Payload>.<Signature>
그렇게 되어서 위의 이미지 처럼 구조가 이뤄진다.
디테일하게 파고드니까 이해가 좀 수월하네.