백엔드 개발에서 가장 중요한 주제 중 하나는 사용자의 데이터를 안전하게 보호하며 인증과 인가를 처리하는 것입니다. 특히, 다양한 서비스 간의 데이터 공유가 필수가 된 환경에서는 안전하면서도 효율적인 인증/인가 방식이 필요합니다.
이 글에서는 JWT라는 핵심 기술을 살펴보고, 각각 백엔드 인증 시스템에서 어떤 역할을 하고 어떻게 협력하는지에 대해 알아봅니다. 여러분은 이 글을 통해 소셜 로그인과 같은 실제 사례에서 이 기술이 어떻게 사용되는지 이해하게 될 것입니다.
JWT는 JSON 형식의 데이터를 안전하게 주고받기 위해 사용하는 토큰 기반 인증 방식입니다. JWT는 주로 사용자의 인증 상태를 유지하거나 정보를 안전하게 전달하기 위해 사용됩니다. 이 토큰은 자체적으로 정보를 포함하고 있어, 별도의 서버 상태 저장 없이도 인증을 처리할 수 있다는 점이 큰 장점입니다.
JWT는 .(점)으로 구분된 3개의 파트로 구성됩니다:
{
"alg": "HS256",
"typ": "JWT"
}
{
"sub": "1234567890", // 사용자 ID
"name": "Federico15", // 사용자 이름
"admin": true // 관리자 여부
}
서명은 토큰이 위조되지 않았음을 보장.
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
- 사용자가 로그인 요청을 보냄.
- 서버는 사용자를 인증하고, 사용자 정보를 담은 JWT를 클라이언트(브라우저나 앱)에 발급.
- 클라이언트는 이 JWT를 저장. (예: 로컬 스토리지, 쿠키).
- 이후 사용자가 서버에 요청을 보낼 때마다 JWT를 포함함.
- 서버는 받은 JWT를 확인하고 사용자를 인증. (서버는 상태를 저장할 필요가 없음).
상태 비저장(Stateless)
서버는 JWT의 정보를 자체적으로 포함하고 있으므로, 세션 정보를 서버에 저장하지 않아도 됩니다.
서버 확장성(Scalability)이 높아지고, 분산 시스템에서 유용합니다.
서명 기반 검증
서명을 통해 토큰이 변조되지 않았는지 확인할 수 있습니다.
비밀키(Secret Key)를 모르면 토큰의 서명을 생성할 수 없으므로, 위조를 방지할 수 있습니다.
만료 시간 설정
exp 필드를 사용해 JWT의 유효 기간을 설정할 수 있습니다. 유효 시간이 지나면 더 이상 사용할 수 없도록 만료 처리가 됩니다.
- 확장성: 서버가 세션 상태를 저장하지 않으므로 대규모 서비스에 적합.
- 독립성: JWT 자체에 필요한 정보가 담겨 있으므로 추가 요청 없이 인증 가능.
- 유연성: JSON 형식이기 때문에 다양한 시스템과 호환 가능.
- 토큰 크기: JWT는 자체적으로 정보를 포함하므로, 일반적인 세션보다 크기가 큽니다.
- 토큰 만료 전 무효화 어려움: JWT는 상태 비저장 방식이므로, 만료되기 전까지는 토큰을 무효화하기 어렵습니다.
- 보안 위험: 토큰이 탈취되면, 만료 전까지 악의적으로 사용할 수 있습니다. 이를 방지하려면 HTTPS를 반드시 사용해야 합니다.
API 인증: 사용자가 API를 호출할 때 JWT로 인증 상태를 확인.
싱글 사인온(SSO): 여러 서비스에서 하나의 인증으로 로그인 상태를 유지.
모바일 앱 인증: 클라이언트-서버 간 통신에서 사용
JWT는 인증(Authentication)을 위한 강력한 도구입니다. 서버는 인증 상태를 저장하지 않고도 클라이언트의 상태를 검증할 수 있으며, 확장성과 독립성이 뛰어나 대규모 분산 시스템에서도 효과적입니다. 그러나 JWT를 안전하게 사용하려면 HTTPS와 짧은 만료 시간, 그리고 토큰 재발급(Refresh Token) 전략을 반드시 고려해야 합니다.
다음포스트에서는 OAuth를 설명하며 JWT와의 관계를 연결할 수 있습니다. 다음 포스트에서 뵙겠습니다! 😊