오늘 배운 것
- JWT
JWT란?
JWT는 Json Web Token의 약자다.
JSON 포맷을 이용해 사용자에 대한 속성 저장하는 Web Token이라는 의미다.
Token은 동전이라는 의미인데 Web Cookie처럼 정보를 담고 있는 것이다.
그래서 그런지 일반적으로 쿠키 저장소를 사용해 JWT를 저장한다.
JWT 사용 이유
로그인에 쿠키-세션 방식과 JWT 방식이 있는데 왜 JWT 방식을 요즘 많이 사용하는지 의문이 있었다.
각각 장단점이 있고 단점을 보완하는 방법도 존재하는 것 같은데 왜 JWT를 많이 사용하는지 궁금했다.
그래서 JWT 사용 이유에 대해서 보자.
서버가 1대인 경우
- 서버가 1대인 경우에는 쿠키-세션 방식을 사용해도 문제가 없다.
- 서버가 모든 클라이언트에 대한 로그인 정보를 서버에 저장하고 있기 때문이다.
서버가 2대인 경우
- 하지만 서버가 1대만 있는 경우는 많지 않을 것이다.
- 대용량 트래픽을 처리하기 위해서 서버 여러 대와 로드밸런서를 사용하는 경우가 많다.
- 이렇게 되면 쿠키-세션 방식의 문제점이 발생한다.
- 세션은 서버 내부에 세션 정보를 저장한다.
- 따라서 각 서버마다 다른 클라이언트에 대한 로그인 정보를 저장하고 있다.
- 이렇게 되면 로드밸런서가 랜덤하게 요청을 여러 서버로 전달한다면
A 서버에서 로그인 상태인 클라이언트가 B 서버에서는 로그인 상태가 아니게 된다.
이런 문제를 해결할 수 있는 방법은 아래와 같다.
- Sticky Session
- 외부 세션 저장소
- JWT
이 중 외부 세션 저장소와 JWT 방식에 대해서 보자.
외부 세션 저장소 생성
- 서버 내부에 세션을 저장해 발생하는 문제로 외부에 따로 세션 저장소를 두는 것이다.
- 외부 세션 저장소에서 모든 클라이언트의 로그인 정보를 소유하고 있다.
- 서버는 외부 세션 저장소에서 세션 정보를 가져와 처리를 한다.
Stikiy Session과 외부 세션 저장소에 관련해 더 자세한 내용은 아래 글을 참고해도 괜찮을 것 같다.
2024.08.23 - [TIL] - 24.08.21 TIL - session clustering
24.08.21 TIL - session clustering
오늘 배운 것session clustering 문제 인식세션로그인을 구현할 때 세션 방식을 사용하는 방법도 있다. 세션 방식 간단히 설명해보겠다. 사용자가 로그인에 성공하면 서버 메모리에 세션 저장소
dev-gongmyoung.tistory.com
JWT
- 세션 방식의 문제점이 서버 내부에 세션을 저장하는 것 때문에 발생한 것이다.
- 따라서 이제 로그인 정보를 서버에 저장하지 않는다.
- 로그인 정보를 JWT에 암호화 해서 저장하는 것이다.
- 그리고 JWT를 클라이언트가 가지고 있다가 서버로 전달하는 것이다.
- 서버에서는 JWT가 왔을 때 검증하면 된다.
- 모든 서버들은 동일한 Secret Key만 가지고 있으면 된다.
- 이 Secret Key로 로그인 정보를 암호화 하고 JWT가 위조 되었는지 검증을 한다.
JWT 장단점
장점
- 동시 접속자가 많을 때 외부의 별도 저장소가 필요 없어 서버측 부하 낮춤
- 인증에 필요한 모든 정보 JWT에 있어 인증을 위한 별도 저장소 필요 없음
- Client, Server가 다른 도메인 사용할 때 사용 가능
- 데이터의 위변조 방지
- 확장성이 좋음
단점
- 구현의 복잡도 증가됨
- JWT에 담는 내용 커질수록 네트워크 비용 증가
- Secret Key 유출 시 JWT 조작 가능
- 특정 토큰 강제 만료 어려움
- JWT 안에 중요 내용 담을 수 없음
JWT 구조
JWT는 누구나 평문으로 복호화 가능하다.
하지만 Secret Key가 없으면 수정 불가능하다.
https://jwt.io에서 복호화 할 수 있다.
JWT는 Header, Payload, Signature로 구성되어 있다.
각 파트는 . 으로 구분해 표현된다.
Header
- Header에는 서명 시 사용하는 키, 토큰의 타입, Signature 암호화 알고리즘의 정보가 담겨있다.
Payload
- payload에는 토큰에서 사용할 정보의 조각들인 claim이 담겨있다.
- claim은 key-value 형태로 저장된다.
- claim에 넣을 값을 개발자가 정해서 넣으면 된다.
- 실제 유저의 정보 들어가 있는 것이다.
- 표준 스펙상으로는 key는 3글자로 되어야 한다.
Signature
- JWT가 변조되지 않았음을 보장하기 위해 사용되는 부분이다.
- Header와 Payload의 인코딩 값, Secret key를 Header에서 정의한 알고리즘으로 암호화 한 것이 담겨있다.
- JWT 검증 시 서버는 Signature를 활용해 JWT의 무결성을 확인한다.
- Header에 명시된 알고리즘과 Secret key를 사용해 Signature를 다시 계산해
JWT의 Signature과 같은지 비교해 변조 여부 판단한다.
JWT 사용 흐름
- 클라이언트가 id, password를 서버로 보내 서버에서 로그인 성공함
- 서버에서 사용자 정보를 secret key를 사용해 JWT로 암호화 함
- 서버에서 쿠키의 value에 JWT를 담아 응답으로 보냄
- 클라이언트 = 브라우저는 쿠키 저장소에 JWT 저장함
- 클라이언트는 이후 요청 시 JWT를 같이 보냄
- 서버에서 JWT를 받고 secret key를 사용해 JWT 위조 여부 검증
- JWT 유효기간 지나지 않았는지 검증
- 검증 성공하면 JWT에서 사용자 정보를 가져와 사용함
느낀 점
JWT에 대해 배우면서 왜 로그인을 구현할 때 JWT 방식을 많이 사용하는지 알게 되었다.
늘 세션도 탈취되면 문제가 되고 JWT도 탈취되면 문제가 되는데 왜 JWT를 사용하는지 의문이 있었다.
심지어 JWT는 안의 내용까지 볼 수 있으면 쿠키의 문제점까지 가지고 있는 것 같은데 왜 JWT 많이 사용하는지 의문이 있었다.
모노리틱 아키텍처와 하나의 서버를 사용해서 프로젝트만 해보니 세션을 사용했을 때의 문제점들을 잘 몰랐던 것 같다.
JWT의 강점은 여러 서버를 가질 때에 문제가 없고 외부 저장소를 가질 필요가 없는 것이 좋은 것 같다.
또 서버에 무엇인가 저장하지 않고 서버에서 secret key만 가지고 있으면 되기 때문에 서버에 부담이 적어 좋을 것 같다.
그리고 JWT는 위변조가 불가능한 것이 중요한 것 같다.
JWT를 탈취해 그 안에 다른 정보를 넣어 다른 사용자의 정보를 받거나 하려고 해도 JWT가 위변조가 불가능하기 때문에 막을 수 있는 것 같다.
'TIL' 카테고리의 다른 글
24.09.02 TIL - Spring Security 동작 원리 (0) | 2024.09.07 |
---|---|
24.08.28 - JWT in Spring (6) | 2024.08.30 |
24.08.26 TIL - 발생 가능 장애 (1) | 2024.08.27 |
24.08.23 TIL - 모니터링 (0) | 2024.08.26 |
24.08.22 TIL - 캐싱 (0) | 2024.08.23 |