JWT (JSON Web Token)
JWT란, 인증에 필요한 정보들을 암호화 시킨 JSON 토큰을 의미한다.
JWT는 JSON 데이터를 Base64 URL-safe Encode 를 통해 인코딩하여 직렬화한 것이며, 토큰 내부에는 위변조 방지를 위해 개인키를 통한 전자서명도 들어있다. 따라서 클라이언트가 JWT를 서버로 전송하면 서버는 서명을 검증하는 과정을 거치게 되며, 검증이 완료되면 응답한다.
Base64 URL-safe Encode 란, 일반적인 Base64 Encode에서 URL에서 오류없이 사용하도록 +, / 를 각각 -, _로 표현한 것이다.
JWT 구조
JWT는 .을 구분자로 해서 3가지 문자열의 조합으로 나타내며, header.payload.signature 로 구성되어 있다.
이거는 이번 프로젝트때 쓰인 access token 을 디코딩해본 모습이다.
header에서는 어느 알고리즘을 사용했는지, payload에서는 subject에 해당하며 사용자의 username을, auth에서는 커스텀 키로, 이 유저의 권한을 나타내며, exp는 만료 시간을, iat는 생성 시간을 나타내고 있다.
signature에서는 header 및 payload를 Base64 URL-soft encode를 할 후 header에 명시된 해시함수를 적용하고, 개인 키로 서명한 전자서명이 담겨있어서 위변조 여부를 확인할 수 있다.
그래서 JWT 자체로는 Base64 decode로 무엇이 쓰여져 있는지 알 수 있지만, 서명이 되어 있기 때문에 header나 payload가 달라지면 이를 알 수 있다.
payload에서 하나의 key-value를 claim 이라 하고, 실제로 사용될 정보들을 여기에 담게 된다.
payload에서는 정해진 데이터 타입은 없지만, 크게 Registered claims, Public claims, Private claims 로 나뉘게 된다.
Registered claims는 미리 정의된 클레임으로, iss(issuer, 발행자), exp(expiration time, 만료시간), sub(subject, 제목), iat(issued at, 발행 시간), jti(JWT ID) 가 있다.
Public claims는 사용자가 정의할 수 있는 공개용 정보 전달을 위해 사용한다.
Private claims는 당사자 간의 정보를 공유하기 위해 만들어진 사용자 정의 클레임으로, 외부에 공개되어도 상관 없지만 해당 유저를 특정할 수 있는 정보들을 담는다.
Signature
위의 사진에서 보였듯, 시그니처는 HS256(Base64Url(header) + . + Base64Url(payload) + . + PrivateKey) 의 결과를 담는다.
JWT 장단점 정리
장점 | 단점 | |
세션 | 쿠키만 사용하는 방식보다 보안 향상 서버 측에서 세션 통제 가능 네트워크 부하 낮음 |
세션 저장소 사용으로 서버 부하 큼 |
JWT | 인증을 위한 별도의 저장소가 필요 없음 별도의 I/O 작업이 없어 빠른 인증 처리 확장성 우수함 |
토큰 길이 늘어날수록 네트워크 부하 큼 토큰을 강제로 만료시키기 어려움 |
JWT 장점
- Signature를 통해 데이터 위변조를 막을 수 있음
- 인증 정보에 대한 별도의 저장소 필요 없음
- 전달할 정보와 검증 증명용 서명 등을 비롯한 필요한 정보를 자체적으로 지님
- 서버측은 무상태로 처리하므로, 확장성이 향상됨
- 다른 로그인 시스템에 접근 및 권한 공유가 가능해짐
- 모바일 앱 환경에서도 잘 동작함
JWT 단점
- 토큰 자체에 정보를 담는 것이 독이 될 수 있음
- 토큰에 정보가 많을수록 길이가 늘어나 네트워크 부하를 줄 수 있음
- Base64로 인코딩 되어 있어서 데이터를 바로 볼 수 있으므로, 중요 데이터를 넣으면 안 됨
- 토큰을 클라이언트 측에서 관리하고 저장하기 때문에, 탈취 당하면 서버측에서는 대처가 어려움
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJleDAxIiwiYXV0aCI6IlJPTEVfVVNFUiIsImV4cCI6MTcwNDIxNDIyNywiaWF0IjoxNzA0MjEwNjI3fQ.dhNpd6EMPXIRmjOSkdSgV1h8kvCBTvx3FL7mHOo8jMA
eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3MDU0MjAyMjcsImlhdCI6MTcwNDIxMDYyN30.CXsWSxnf0oNBgSKqMCMGg4-tdMcrpWT473nyHaBy9Mk
위는 이번 프로젝트에서 쓰인 access token, 아래는 refresh token 인데 refresh token에는 어느 정보도 담지 않았고, 그래서 길이가 많이 짧아진 것을 볼 수 있다.
참고 링크
'TIL ✍️' 카테고리의 다른 글
24년 1월 4일(목요일) - 64번째 TIL (1) | 2024.01.05 |
---|---|
24년 1월 3일(수요일) - 63번째 TIL (0) | 2024.01.04 |
23년 12월 28일(목요일) - 61번째 TIL (1) | 2023.12.28 |
23년 12월 27일(수요일) - 60번째 TIL (0) | 2023.12.27 |
23년 12월 26일(화요일) - 59번째 TIL (0) | 2023.12.26 |