서두에서 말했듯이 JWT ( JSON Web Token )는 API 인증, 마이크로서비스 간 통신, SSO(Single Sign-On ) 등 현대 웹 서비스에서 굉장히 많이 사용되며 JWT의 구조와 역할을 모를 경우 여러 실수를 범할 수 있기 때문이다.
위에서 말한 범할 수 있는 실수는 아래와 같다.
이번 글에서는 이러한 이유로 JWT를 구성하는 크게 세 가지 요소들을 하나씩 뜯어보며, 어떤 역할을 하는지 이해해보겠다.
예시 JWT
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJzdWIiOiJ1c2VyMTIzIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImV4cCI6MTczNTY4OTYwMH0
.fuX1xj1kJ-tLmJzG3c29f94UJckZBjhI7mFkYgH1UO0
토큰 타입과 서명 알고리즘을 지정하는 역할을 한다.
EX
{
"alg": "HS256",
"typ": "JWT"
}
alg -> 서명 알고리즘 ( ex : HS256, RS256 )
typ -> 토큰 타입 (JWT)
⚠ alg를 none으로 설정하면 서명 검증 없이 통과하는 취약점이 발생할 수 있다.
{
"sub": "user123",
"name": "John Doe",
"admin": true,
"exp": 1735689600
}
⚠ 중요 : Base64URL 인코딩은 암호화가 아니기에 누구나 디코딩이 가능하므로 비밀번호/카드번호 등 민감 정보는 절대 넣어서는 안된다 ❗❗
JWT는 기본적으로 서명(Signing)만 제공하며, 암호화(Encryption)는 JWE에서 다룬다.
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret_key
)
1️⃣ 사용자가 로그인을 요청
2️⃣ 서버에서 인증 성공 시 JWT 발급
3️⃣ 클라이언트는 토큰을 localStorage, Cookie 등과 같은 곳에 저장
4️⃣ API 요청 시 Authorization 헤더에 첨부
Authorization: Bearer <JWT>
5️⃣ 서버는 서명 검증 후 응답
📌 한눈에 보기 좋게 정리
[User] -> 로그인 요청 -> [Server]
[Server] -> JWT 발급 -> [User]
[User] -> API 요청(JWT 포함) -> [Server]
[Server] -> 서명 검증 후 응답
이렇게 오늘 JWT 토큰 구조와 각 구성 요소 그리고 동작흐름까지 알아보았다.
JWT는 간단하지만 강력한 인증/인가 도구이다.
오늘 알아본 구성 요소의 의미와 동작 원리를 이해하면 보안에 강하고 유지보수하기 좋은 인증 시스템을 만드는데 도움이 될 것이다 💯