본문 바로가기

Spring이론

JWT(JSON Web Token)의 개념과 이해

반응형

JWT(JSON Web Token)은 JSON 기반의 토큰 형식으로, 주로 인증과 정보 교환에 사용됩니다.
서버와 클라이언트간의 안전한 통신을 위해 만들어졌으며, 정보는 디지털 서명으로 서명되어 있어 신뢰성을 보장할 수 있습니다.

 

1. JWT의 구조

JWT는 세 부분으로 나뉘며, 각 부분은 . 으로 구분됩니다.

 

Header (헤더): 토큰의 메타정보를 담고 있습니다.

Payload (페이로드): 토큰에 담길 claim(실제 데이터)을 포함합니다.

Signature (서명): 헤더와 페이로드를 바탕으로 생성된 서명으로, 토큰의 무결성을 보장합니다.

 

1) Header

Header는 토큰의 타입(JWT)과 서명에 사용할 해시 알고리즘을 명시합니다.

아래는 Header의 예시 입니다.

{
  "alg": "HS256",
  "typ": "JWT"
}

 

2) Payload

페이로드에는 토큰에 담길 실제 데이터를 담고 있습니다. 이 데이터를 claim이라고 부릅니다.

해당 claim에는 발급자, 만료시간, 유저 이메일 등이 담겨 있습니다.JWT의 구조는 매우 유연하기 때문에 특정 상황이나 필요에 따라 claim을 추가하거나 제외할 수 있습니다.아래는 Payload의 예시 입니다.

{
  "name": "Pinlib",
  "admin": true
}

 

3) Signature

서명은 헤더와 페이로드의 무결성을 검증하는 데 사용됩니다. 보통 비밀 키를 사용해 HMAC, 또는 공개 키를 사용해 RSA나 ECDSA로 서명됩니다. 이를 통해 누군가가 JWT를 위변조했는지 확인할 수 있습니다.

 

여기서 HMAC(Hash-based Message Authentication Code, 해시 기반 메시지 인증 코드)는 데이터의 무결성과 출처를 확인하는 방식으로, 해시 함수와 비밀 키를 결합하여 사용됩니다. HMAC은 주어진 메시지가 중간에 변조되지 않았는지 확인하고, 해당 메시지가 신뢰할 수 있는 발신자로부터 왔는지 검증하는 데 활용됩니다.

 

RSA란 가장 널리 사용되는 공개 키 암호화 알고리즘 중 하나입니다. 비대칭 암호화 방식으로, private key와 public key를 사용하는데 private key로 토큰의 헤더와 페이로드에 서명하고, 수신자는 public key로 서명을 검증하게 됩니다. 

 

ECDSA는 타원 곡선 암호화(Elliptic Curve Cryptography, ECC)를 기반으로 하는 서명 알고리즘입니다. RSA와 마찬가지로 비대칭 암호화 방식이며, private key와 public key를 사용합니다. 그러나 ECDSA는 RSA와는 다른 수학적 기초인 타원 곡선을 사용합니다.

 

아래는 Signature의 예시입니다.

HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)

 

이 코드는 header와 payload를 Base64Url로 인코딩하고 결합해줍니다.여기서 Base64는 바이너리 데이터를 ASCII 문자열 형식으로 인코딩하는 방법입니다. 여기서 Base64Url의 경우 Base64를 Url에 적용하기 좋게 업그레이드 한 것으로 보시면 됩니다.

 

secret의 경우 서명을 생성하기위한 비밀키입니다. 

 

마지막으로 결합된 문자열과 비밀키를 입력으로 받아 HMACSHA256 해시함수를 적용하여 서명을 생성합니다.여기서 HMAC의 경우 데이터의 무결성과 출처를 확인하는 방식으로, 해시 함수와 비밀 키를 결합하여 사용됩니다. HMAC은 주어진 메시지가 중간에 변조되지 않았는지 확인하고, 해당 메시지가 신뢰할 수 있는 발신자로부터 왔는지 검증하는 데 활용됩니다.

 

여기서 SHA256을 사용하였는데 SHA-256은 256비트의 고정 길이 해시값을 생성하는 암호화 해시 함수입니다.

 

따라서 JWT는 rhjeslkrjhs.fsaefse.afsdf 이런 형식으로 header, payload, signaturea로 . 을 통해 결합된 후 암호화 되어 나타나게 됩니다.

 

2. JWT의 특징

1) 무상태성

JWT는 자체적으로 필요한 정보를 모두 담고 있어 서버 측에서 세션 상태를 유지할 필요가 없습니다.

서버는 클라이언트의 요청을 받을 때 토큰만 검증하면 되므로 서버의 부담이 줄어듭니다.

 

2) 자체 포함

JWT에는 사용자 정보 및 토큰 만료 시간 등의 데이터가 포함되어 있어, 토큰 자체만으로도 필요한 정보를 추출할 수 있습니다.

 

3) 보안성

Signature를 통해 토큰이 위변조되지 않았음을 보장합니다.

하지만, JWT는 암호화되지 않으므로 중요한 정보(비밀번호 등)를 담아서는 안 됩니다.

데이터는 Base64Url로 인코딩되며, 누구든지 이를 디코딩해 내용을 확인할 수 있습니다.

 

 

3. JWT 사용 사례

1) Authorization(인증)

사용자 인증 후 서버는 JWT를 클라이언트에 발급하고, 클라이언트는 이후 모든 요청에 JWT를 헤더에 포함해 서버로 보냅니다. 서버는 토큰을 검증해 사용자의 인증 상태를 확인합니다.

 

2) 정보 교환

JWT는 양 당사자가 신뢰할 수 있는 방식으로 정보를 교환할 때 사용됩니다. 토큰은 서명되므로 중간에서 수정되지 않았음을 보장합니다.

 

 

 

4. Cookie, Session, JWT 비교

cookie, session, JWT는 모두 웹 애플리케이션에서 사용자 인증 및 상태관리를 위한 기술이지만, 사용하는 방식과 동작 원리가 다릅니다.이제부터 각 개념에 대해 설명하겠습니다.

 

1) Cookie

쿠키는 웹 브라우저에 의해 클라이언트 측에 저장되는 작은 데이터 조각입니다.

서버가 클라이언트에 일부 정보를 저장하도록 요청하고, 이후 HTTP 요청마다 이 정보를 서버로 다시 전송합니다.

 

쿠키는 세션을 저장하거나 브라우저 측에서 사용자 정보를 유지할 때 유용합니다. 서버와 클라이언트 간 작은 정보(예: 세션 ID, 사용자 설정)를 주고받을 때 사용됩니다.

 

Cookie 장점

- 클라이언트가 쿠키를 자동으로 서버에 전송하므로 인증 정보가 클라이언트-서버 간에 쉽게 전달됩니다.

- 만료 기간을 설정하여 쿠키의 생명주기를 제어할 수 있습니다.

 

Cookie 단점

- 보안 취약성: 쿠키는 클라이언트에 저장되므로 XSS(Cross-Site Scripting) 공격에 취약할 수 있습니다. 이를 방지하기 위해 HttpOnly, Secure, SameSite 속성을 설정해야 합니다.

- 쿠키 크기는 최대 4KB로 제한되어 있으며, 이로 인해 많은 데이터를 저장할 수 없습니다.

 

2) Session

세션은 서버 측에서 사용자 상태를 저장하는 방식입니다. 사용자가 로그인하거나 특정 작업을 수행할 때, 서버는 사용자와의 세션을 생성하고 이를 세션 ID로 식별합니다.

 

세션을 사용하는 경우는 사용자 세션을 중앙에서 관리해야 할 때 사용됩니다. 주로 전통적인 웹 애플리케이션이나 서버 자원이 충분하고 사용자가 많지 않은 환경에서 적합합니다.

 

Session 장점

- 세션 데이터는 서버에서 관리되므로, 클라이언트는 세션 ID만 제공하면 됩니다. 서버가 세션을 제어하고 있기 때문에 높은 보안성을 제공할 수 있습니다.

- 서버 측에서 세션 만료 시간이나 로그아웃 등을 직접 제어할 수 있습니다.

 

Session 단점

- 상태를 서버가 유지하기 때문에, 사용자가 많아질수록 서버 자원이 많이 소모됩니다.

- 서버 측에서 세션 만료 시간이나 로그아웃 등을 직접 제어할 수 있습니다.

 

3) JWT

개념에 대한 설명은 위에서 했으므로 생략하겠습니다.

 

JWT의 경우 무상태성이 필요한 애플리케이션에서 많이 사용됩니다. 예를 들어, 모바일 앱, SPA(Single Page Application)와 같은 서버에 많은 부하를 주기 어려운 환경에서 주로 사용됩니다.

그리고 분산된 서버 환경에서 세션을 공유하기 어려울 때 유용합니다.

 

JWT  장점

- 서버의 부담을 줄이고, 확장성 있는 분산 서버 환경에 적합합니다.

- 사용자 정보와 만료 시간 등을 토큰 내에 포함할 수 있어 추가 데이터 조회 없이도 인증 정보를 처리할 수 있습니다.

 

JWT 단점

- 토큰이 탈취되면 만료 기간 동안 악용될 수 있습니다.

- 토큰 크기가 커질 수 있으며, HTTP 요청마다 전송되므로 네트워크 성능에 약간의 영향을 미칠 수 있습니다.

 

 

위 장단점에 대하여 요약식으로 표로 보여드리겠습니다.

항목 JWT session cookie
상태 관리 서버에서 상태 유지 안 함 서버에서 상태 유지 클라이언트 측에서 상태 관리
저장 위치 클라이언트(local storage, 쿠키) 서버 클라이언트(브라우저)
인증 방식 토큰 기반 인증 세션 ID 기반 인증 쿠키에 세션 ID 저장 후 사용
보안성 서명으로 무결성 보장 서버에서 세션 직접 관리 보안 속성 설정 필요(HttpOnly 등)
확장성 서버 부담 적음, 확장성 높음 서버에 세션 저장으로 부담 큼 확장성은 쿠키 자체로는 없음
크기 제한 토큰 크기 제한 없음(다소 큼) 세션 데이터는 서버에만 저장됨 최대 4KB
탈취 위험 탈취 시 만료 전까지 악용 가능 세션 ID 탈취 시 위험 쿠키 탈취 시 위험

 

 

글을 마무리하며

요즘에는 웹 애플리케이션과 API 인증에서 JWT(JSON Web Token)를 많이 사용하는 경향이 있습니다.

그러나 쿠키와 세션도 여전히 특정 시나리오에서 사용되며, 선택은 프로젝트의 요구 사항과 환경에 따라 다릅니다. 

즉, 필요에 따라 사용하시면 됩니다.

 

이렇게 이번 JWT(JSON Web Token)의 개념과 이해에 대한 글은 마무리하겠습니다.다음번에는 JWT를 spring과 android에 적용하는 방법에 대한 주제로 돌아오겠습니다. 긴 글 읽어주셔서 감사합니다.

 

 

 

반응형