JWT의 등장 배경
과거 - 쿠키와 세션으로 가득 했던 인증 체계
로그인 유지의 문제
➡️ 데이터베이스에 저장된 사용자 계정의 해시값 등등을 꺼내옴 → 사용자의 암호를 복잡한 알고리즘으로 계산한 값과 일치하는 지 확인
- 이 과정을 매 요청마다 하기에는 무겁고 복잡한 과정이라 부담스럽다.
- 매 요청마다 아이디와 패스워드가 이동하면 보안상으로 위험하다.
쿠키
: 브라우저에서 저장되는 키와 같이 사이트가 사용하게 되는 일련의 작은 기록 파일
특정 정보를 저장하기 위해 사용했다. 매번 요청 할 때마다 사용자가 로그인 시도를 하지 않게
쿠키의 단점
- 노출되었을 때, 민감 정보까지 다 노출되어 보안이 좋지 않음
- 조작 당해서 들어올 가능성이 있다.
- 웹 브라우저마다 쿠키에 대한 지원 형태가 달라 다른 브라우저간의 공유가 불가능
- 쿠키의 사이즈 제한(4kb)으로 그 이상의 데이터를 담을 수 없음
- 서버는 매번 로그인 정보를 받아 인증을 해야함(사용자의 편의성만 있다)
- 서버는 조작된 데이터가 넘어오는 경우를 방지할 수 없다.
세션
: 세션 ID를 사용해 어떤 사용자가 서버에 로그인 되어있음이 지속되는 상태를 세션이라고 한다.
(웹애플리케이션과 클라이언트간의 상호작용을 유지하기 위한 개념)
개인 민감정보를 그대로 노출했을 때의 단점을 막기 위해 등장
로그인 정보를 주고받지 않고 인증 정보 자체를 특정 세션 저장소에 저장.
클라이언트가 로그인을 시도하면 로그인 정보가 담긴 쿠키와 세션 저장소의 정보가 동일한지 판단하여 로그인 인가
데이터를 서버에 두기 때문에 쿠키보다 보안이 좋다.
세션의 허점
- 사용자가 많아질수록 서버 메모리를 많이 차지함 → 메모리는 휘발성이라 서버에 문제가 생기면 정보가 날아갈 수 있다.
say good bye~ - 세션 저장소가 필수적으로 존재하기 때문에 이를 위한 비용 발생(서버 메모리 할당)
- 서비스 규모가 커서 서버를 여러개 둔 경우, 1번 서버에서는 인증을 받아도 3번 서버에서는 받지 않았기 때문에 세션유지가 안된다.
- http의 장점이라 할 수 있는 statless를 위배한다. (stateful하다)
→ 위의 허점을 피하면서 인가를 구현하기 위해 고안된게 토큰 방식
JWT란?
페이지가 다시 로드 될 때마다, 로그인을 한다면 얼마나 불편할까 로그인을 확인하는 것 뿐만 아니라 로그인을 유지시키는 것도 어렵다.
JWT는 JSON 웹 토큰(JSON Web Token)의 약자로 전자 서명 된 URL-safe (URL로 이용할 수있는 문자 만 구성된)의 JSON입니다.
JWT는 일반적으로 클라이언트와 서버 간에 사용자 데이터를 안전하게 전송하는 수단.
토큰은 서버에서 생성되어 저장되는 클라이언트로 전송된다. 그런 다음 클라이언트는 각 후속 요청과 함께 토큰을 전송하여 서버가 사용자 이름과 암호를 계속 확인하지 않고도 사용자를 인증하고 권한을 부여할 수 있도록 한다.
➕ 인증(Authentication) 로그인, 특정 서비스에 일정 권한이 주어진 사용자임을 아이디와 패스워드를 통해 인증을 받음
➕ 인가(Authorization) 한번 인증을 받은 사용자가 이후 로그인 상태에서만 사용할 수 있는 서비스의 여러 기능들을 사용할 때, 인증(로그인)을 확인하고 허가를 해줌 로그인이 유지되는 상태에서 일어나는 일 → JWT는 인가와 연관된 기술
JWT 장점
- JWT 의 주요한 이점은 별도의 인증 저장소가 필요없다는 것. → 서버와의 커뮤니케이션 오버 헤드를 최소화
- 서버와 데이터베이스에 의존하지 않는 쉬운 인증 및 인가 방법을 제공.
- Cross-Origin Resource Sharing (CORS)는 쿠키를 사용하지 않기 때문에 JWT를 채용 한 인증 메커니즘은 두 도메인에서 API를 제공하더라도 문제가 발생하지 않는다.
- 트래픽에 대한 부담이 낮다.
JWT 토큰 구성
JWT는 헤더, 페이로드, 서명의 세 부분으로 구성되며, 각 파트는 점로 구분하여 xxxxx.yyyyy.zzzzz으로 표현된다.
(인코딩 or 암호화가 된 3가지 데이터를 이어붙여 만듬)
헤더 (Header)
- 서명을 생성하는 데 사용되는 토큰 유형 및 해싱 알고리즘에 대한 정보가 포함되어 있다.
type : JWT(고정값)
alg : 3번 서명을 만드는 데 사용될 알고리즘 지정
.
.
.
페이로드(Payload)
- → 미리 정보를 보내기 때문에 서버가 사용자의 요청마다 일일이 데이터베이스에서 정보를 찾을 필요가 줄어든다.
- 토큰이 전달하는 클레임 또는 데이터가 포함된다. Base64로 디코딩 해보면 JSON형식으로 **클레임(Claim)**이 들어있다. 페이로드 만으로 토큰을 구성하면 Base64로 디코딩해 악용을 할 여지가 있으므로 다른 2개의 데이터를 더 붙임
➕ 클레임(Claim) : 토큰에 담긴 사용자 정보등의 데이터 페이로드에 담는 정보의 한 ‘조각’ 을 클레임이라고 부르고, name / value 의 한 쌍으로 이뤄져있다. 토큰에는 여러개의 클레임 들을 넣을 수 있다.⚠️ 디코딩이 되어있을 뿐 특별한 암호화가 걸린 건 아니기 때문에 민감한 정보를 담지 않아야한다.
➕ Base64 8비트 이진 데이터를 문자 코드에 영향을 받지 않는 공통 ASCII 영역의 문자들로만 이루어진 일련의 문자열로 바꾸는 인코딩 방식을 가리키는 개념이다.
- 서명(Signature)
1번 헤더와 2번 페이로드 + 서버에 저장한 secret key ⇒ 서명 값 완성 전송 중에 토큰이 변조되지 않았는지 확인하는 데 사용되며 secret key의 존재로 인해 악용하기 어렵다.
!https://velog.velcdn.com/images/leemember/post/2bcb1d35-3167-4888-bbce-c04f945b61d6/image.png
JWT process
http://www.opennaru.com/opennaru-blog/jwt-json-web-token/
- 사용자가 id와 password를 입력하여 로그인
- 서버는 요청을 확인하고 Access token을 발급 → JWT 토큰을 클라이언트에 전달(서버는 기억하지 않음)
- 클라이언트에서 API 을 요청할때 클라이언트가 Authorization header에 Access token을 담아서 전송.
- 서버는 JWT 서명를 체크하고 페이로드로부터 사용자 정보를 확인해 데이터를 반환.
- 클라이언트에 요청에 대한 응답을 전달
JWT와 세션 기반 인증의 차이점(JWT의 단점)
👁️🗨️ 상황 한 기기에만 로그인이 가능한 서비스를 만들려는 경우
세션
- 모든 사용자들의 상태를 기억하면 구현하기 부담되고 고려사항이 많지만 기억하는 대상의 상태를 언제든 제어 가능 → 다른 기기에 로그인을 할 경우 이전에 로그인된 기기는 세션을 만료해 로그아웃 처리
JWT
- 이미 발급된 토큰을 제어할 수 없다. 무효화 할 수 없다. 발급된 토큰의 내역을 서버에 기록하고 추적하지 않는다. → 통제 불가
악용을 막아보자(한계 max)
1. 훔치기 어려운 저장소(HttpOnly cookie)에 토큰 저장 HttpOnly cookie : 브라우저에서 쿠키에 접근할 수 없도록 제한
2. JWT 블랙리스트 운영(세션과 동일해짐)
보완책(한계 O)
로그인을 하면 토큰을 두 개 발급 access 토큰 : 토큰의 수명을 짧게 발급 refresh 토큰 : 토큰의 수명을 길게 발급(보통 2주) access 토큰을 재발급 받기 위해 사용
refresh 토큰은 상응값을 데이터베이스에도 저장
클라이언트는 access 토큰의 수명이 다하면 refresh 토큰을 서버로 보냄
서버는 데이터베이스에 저장된 값과 대조하여 맞다면 새 access 토큰 발급
refresh token 조차 훔칠 수 있지 ㅋㅋㅋ…!
refresh token rotation : refresh token은 언제나 1회용으로 재발급 필요하게 함
➡️ 그래서 실 서비스 중에 JWT로만 이뤄진 건 많이 없다고함
이용자가 많거나 마이크로 서비스가 많다면 jwt
보안이 중요하면 JWT를 세션처럼 땜빵칠 한다고…
참고자료
JWT (JSON Web Token) 이해하기와 활용 방안 - Opennaru, Inc.
🧑🏻🏫 프론트엔드 기술 면접 단골 개념들 정리 (네트워크 / CS 편 / 그 외 질문)
JWT란 무엇인가? 그리고 어떻게 사용하는가? (1) - 개념
JWT는 어디에 저장해야할까? - localStorage vs cookie
'CS > 네트워크' 카테고리의 다른 글
CORS(교차 출처 리소스 공유) (1) | 2023.07.09 |
---|---|
CORS / CORS 해결방안 / 처리 방법 (0) | 2023.07.09 |
HTTP 요청 메소드 POST와 GET의 차이 (0) | 2023.07.02 |
REST API (0) | 2023.07.02 |
HTTP와 HTTPS의 차이_민희 (0) | 2023.06.25 |