안녕하세요.
JWT(json web token) 에 대해서 알아보겠습니다.
JWT란?
json web token의 약자로 웹 상에서 정보를 Json 형태로 주고 받기 위해 표준규약에 따라 생성한 암호화된 토큰입니다.
언제 사용되는가?
- Authorization : 가장 보편적으로 많이 사용되는 시나리오입니다. 로그인 인증 후 이후 요청에 jwt를 포함하여 요청을 보내면 토큰을 통해 서버가 인증을 확인합니다. 작은 오버헤드와 다른 도메인에 쉽게 사용할 수 있다는 점을 특징이고 SSO(Single Sign On)할 수 있습니다.
- Information Exchange : 안전하게 정보교환하기 유용합니다. 개인, 공개키를 통해 서명되어 있어 안전합니다. 게다가 서명은 헤더와 payload를 통해 만들어지기 때문에 변조가 되었는지 파악할 수 있습니다.
JWT의 구성요소?
아래 일반적인 jwt 구조입니다.
xxxxx.yyyyy.zzzzz
xx 부분이 header, yy 부분이 payload, zz 부분이 signature 입니다.
- Header(헤더)
- 헤더는 보통 JWT가 어떤 타입인지, 서명 알고리즘이 어떤 알고리즘인지에 대한 정보를 가지고 있습니다.
- 그 다음 BASE64로 인코딩하여 위 xxxxx부분이 됩니다.
{
"alg": "HS256",
"typ": "JWT"
}
- Payload(정보)
- payload는 claim들로 구성됩니다. claim이란 엔티티(사용자)에 대한 정보나 추가로 담고 싶은 정보(설명) 입니다. claim 종류는 registered, public, private으로 나뉩니다. claims 이름은 압축되어 3자로 표현합니다.
- registerd claims : 필수는 아니지만 권장하는 claims
- iss (issuer), exp (expiration time), sub (subject), aud (audience), and others.
- public claims : 원하는대로 정의해서 사용할 수 있습니다. 하지만 충돌방지를 위해 https://www.iana.org/assignments/jwt/jwt.xhtml 에 정의해서 사용?하거나, 충돌방지 네임스페이스가 포함된 URI 사용
- private claims : 커스텀해서 사용
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
보통 구현할때 registerd claims 중 sub를 활용해서 사용자 식별값을 담아서 주고받는 것으로 이해했습니다.
추가로 exp를 활용해서 토큰 만료시간을 알 수 있습니다.
payload도 마찬가지로 Base64로 인코딩하여 yyyyy 부분을 채웁니다.
서명된 토큰의 경우 변조로 부터 보호받을 수 있지만 누구나 읽을 수 있습니다.
데이터 값이 암호화 되지 않은 경우 jwt payload 나 header에 데이터를 넣지 않는 것이 좋습니다.
- Signature(서명)
- 서명 부분을 생성하려면 인코딩된 헤더, 인코딩된 페이로드, secretKey, 헤더에 지정된 알고리즘이 필요합니다.
- 만약 HMAC SHA256 를 사용한다면 아래와 같이 서명이 진행됩니다.
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
서명은 메세지가 도중에 변조되지 않았는지 확인하는데 사용됩니다.
개인 키로 서명된 토큰의 경우 JWT 발신자가 누구인지 확인할 수도 있습니다.
HTML 및 HTTP 환경에서 쉽게 전달할 수 있는 점으로 구분된 3개의 Base64-URL 문자열이며, SAML과 같은 XML 기반 표준과 비교할 때 더 간결합니다.
조합하기
위 3개의 구성요소를 HTML 및 HTTP 환경에서 쉽게 전달할 수 있는 점으로 하나의 문자열을 만듭니다.

이렇게 JWT를 만들어보았습니다!
그렇다면 어떻게 JWT를 사용하여 Authorization을 하는지 알아보겠습니다.
JWT 인증 동작과정

1. 서버에 인증 요청을 보냅니다.
2. 인증이 통과되면 access token을 발행합니다.
3. authorization header로 Bearer 을 prefix로 (2)에서 받은 access token을 넘깁니다. 해당 access token을 통해 api 서버 자원에 접근할 수 있습니다.
해당 인증방식은 무상태 인증 방식입니다. (세션과 다르게 어떤 서버에 접근해도 같은 상태를 알 수 있기 때문에?) (세션도 중앙 디비로 관리한다면 무상태 인증할 수 있는 것으로 압니다.)
토큰을 헤더에 실어서 가기때문에 토큰 크기가 너무 크지않도록 주의해야합니다.
정리
- jwt는 json web token으로 웹상에서 json 형태로 정보를 주고받기 위해 표준규약으로 생성된 암호화된 토큰이다. (어려워~)
- jwt 구성요소는 header, payload, signature 가 있다.
- 헤더에는 jwt 종류, 서명 알고리즘에 대해 있고 payload는 여러 claims들, 서명에는 header와 payload가 서명 알고리즘으로 암호화된 정보가 담긴다.
- 위 3개의 조합으로 jwt가 만들어진다.
- 인증방식 복기..
keywords
- 암호화방식 : 공개키/개인키, 대칭키, 비대칭키 >> 서명을 이해하기 위해서 필요함
- HMAC SHA256 또는 RSA 등 여러 알고리즘,,, 이건 다음에,,
- https://www.youtube.com/watch?v=O7SiDuTCysM -> 5분컷
- 디지털 서명
- JSON
- 무상태 인증 > 유저정보가 서버가 아닌 유저에게 있다!!!
- 아니 근데 jwt도 refresh 토큰 등 고도화하면 디비로 정보 관리하던데 흠?
- 세션도 브라우저에 세션id 가지고 있는데..
- 유저정보, 만료시간 등 통째로 들고 있어야 맞나보다. 그래야 서버상관없이 stateless라 할 수 있을까
- 아 서버가 이전 요청에 대해 기억을 하고 있는지 없는지가 판단 기준이다.
- 토큰이 Authorization헤더로 전송되면 CORS(Cross-Origin Resource Sharing)는
쿠키를 사용하지 않으므로 문제가 되지 않습니다?? - jwt와 세션 차이
next?
다음 시간에는 springboot3 에서 jwt를 사용한 인증을 구현해보겠습니다. 이만
참고
'Computer Science > 네트워크' 카테고리의 다른 글
| [ACL] ACL이 뭔데요? (3) | 2024.04.07 |
|---|---|
| CORS란? (0) | 2022.09.02 |