티스토리 뷰
JWT
JWT
는 Json
포맷을 이용하여 사용자에 대한 속성을 저장하는 Claim
기반의 Web Token
을 말한다.
세션은 서버에 사용자 정보를 저장하기 때문에 서비스를 이용하는 사용자가 많으면 그만큼 저장할 공간도 더 필요하며,
분산서버에서는 세션을 공유(A서버에 저장된 세션 ID로 B서버에서 인증)하는데 어려움이 존재하는 등의 단점이 존재한다.
이런 세션의 단점을 해결하기 위해서 토큰으로 인증하는 방법을 사용할 수 있는데, 유저가 로그인을 하면 서버에서는 토큰을 생성한 뒤에 저장하지 않고(stateless
) 토큰값을 내려준다. 사용자는 이 토큰 값과 함께 서버에 요청하면 A서버든, B서버든 상관없이 토큰 값을 토대로 유저를 인증한다.
토큰 방식의 장점
- 세션관리를 할 필요가 없어 별도의 저장소가 필요하지 한다.
- 서버 분산&클러스터 환경과 같은 확정성에 좋다.
토큰 방식의 단점
- 한번 제공된 토큰은 회수가 어렵다. 세션의 경우에는 서버에서 세션을 삭제하면 브라우저의
JSESSIONID
는 무용지물이 되어버리는 반면, 토큰은 세션을 저장하지 않기 때문에 한 번 제공된 토큰을 회수할 수 없다. 그래서 보통 세션의 유효기간을 짧게 한다. - 토큰에는 유저의 정보가 있기 때문에 민감한 정보를 토큰에 포함시키면 안 된다.(패스워드, 개인정보)
JWT의 구조
JWT
는 HEADER.PAYLOAD.SIGNATURE의 구조를 갖는다.
eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ1c2VyIiwicm9sZXMiOl.hHkvviDzMIx8EkXUTZsNLWGy51p2 bVnJknEC0HYxMaRkXGQJdIWqIX1Rv8rGK6bMq6mYyGES3jxNJVPz33wvEQ
Header
Header
는 JWT
를 검증하는데 필요한 정보를 가진 객체이다.Signature
에 사용한 암호화 알고리즘이 무엇인지, Key
의 ID
가 무엇인지에 대한 정보를 Json
으로 변환해서 UTF-8
로 인코딩한 뒤, Base64 URL-Safe
로 인코딩한 값이 들어가 있다. 결과 값이 다소 난해한 문자로 보이지만, 암호화된 값은 아니다.
Payload
Payload
는 실질적으로 인증에 필요한 데이터를 저장하며, 데이터의 필드들을 Claim
이라고 한다.
인증할 때 Payload
의 username
으로 유저 정보를 조회해야 하기 때문에 Claim
은 username
을 포함하고 있다.Header
와 마찬가지로 암호화된 값이 아닌 Json
으로 바꾼 뒤 UTF-8
로 인코딩하고 Base64
로 변경한 데이터일 뿐이다.
Signature
JWT
의 구조에서 가장 마지막에 있는 Signature
는 토큰 자체의 진위여부를 판단하는 용도로 사용된다. Signature
는 Header
와 Payload
를 합친뒤 비밀키로 Hash
를 생성하여 암호화한다.
Header.Payload
값을 SecretKey
로 Hashing
하고 Base64
로 변경한다.
Key Rolling
JWT
의 토큰 생성 메커니즘을 살펴보면 Secret Key
의 노출은 곧 모든 데이터의 유출이라는 것을 알 수 있다.
이런 문제를 방지하기 위해서, 여러 개의 Secret Key
를 주기적으로 추가/삭제하며 변경하는 것을 Key Rolling
이라 말한다. 이 경우 Secret Key
가 노출되어도 다른 Secret Key
와 데이터는 안전하다. (필수 X)
Key Rolling
에서는 여러개의 Secret Key
가 존재한다. Secret Key
1개에 Unique
한 ID
(kid
혹은 key id
라고 부름)를 연결시켜 둔다. JWT
토큰을 만들 때, 헤더에 kid
를 포함하여 제공하고, 서버에서 토큰을 해석할 때 kid
로 Secret Key
를 찾아서 Signature
를 검증한다.
'Spring' 카테고리의 다른 글
[Spring] 웹 서버(Web Server)와 웹 어플리케이션 서버(WAS)의 차이가 무엇일까? (1) | 2022.08.27 |
---|---|
[Spring] 스프링 트라이앵글 - IoC/DI, AOP, PSA (0) | 2022.08.26 |
[Spring] AOP @target, @within (0) | 2022.06.06 |
[Spring] AOP Pointcut execution (0) | 2022.05.31 |
[Spring] Advice 종류 (0) | 2022.05.29 |
- Total
- Today
- Yesterday
- spring boot
- 리팩토링
- 파이썬
- 스프링 부트
- Algorithm
- 자료구조
- Refactoring
- 정렬
- webflux
- 알고리즘
- 백준
- Real MySQL
- 릿코드
- 노마드
- mysql 8.0
- 코테
- 노마드코더
- Spring
- 문자열
- 김영한
- 그리디
- 구현
- 인프런
- leetcode
- 스프링
- 북클럽
- 코틀린
- kotlin
- 데이터베이스
- MySQL
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |