서버가 클라이언트를 인증하는 방식으로 대표적인 쿠키, 세션, JWT가 있습니다.
HTTP 특성
HTTP 프로토콜은 다음 특성을 지니고 있습니다.
- 비연결성(Connectionless)
비연결성
은 클라이언트가 요청을 한 후 응답을 받으면 연결을 끊어 버리는 특성입니다.
- 무상태(Stateless)
무상태
는 서버가 클라이언트의 이전 상태를 보존하지 않는 특성입니다.
HTTP의 위 특성으로 인해 서버는 기본적으로 클라이언트를 기억하지 않습니다. 쿠키와 세션을 이용하여 클라이언트를 구별하고 기억할 수 있습니다.
쿠키 (Cookie) 🍪
클라이언트에 저장되는 key-value
형식의 데이터
- 클라이언트가 서버로 요청
- 서버가 쿠키를 생성한 후
Set-Cookie
를 응답 헤더에 담아서 클라이언트에 전송 - 다음 요청부터 클라이언트는 요청 헤더의
Set-Cookie
에 쿠키를 담아서 요청 - 서버에서 쿠키 확인
쿠키의 활용
- 쇼핑몰의 장바구니 기능
- 사용자 설정 저장 (다크모드)
쿠키 방식의 단점
- 보안에 취약 (데이터들을 서버가 아닌 클라이언트에 보관하고 있기에 유출 및 조작될 위험이 크다.)
- 쿠키에는 용량 제한이 있어 많은 데이터를 담기 어려움. (클라이언트에 300개까지 쿠키 저장 가능, 하나의 도메인당 20개의 값만 가질 수 있음, 하나의 쿠키 값은 4KB까지 저장 가능)
- 쿠키에 저장된 데이터가 클 수록 네트워크 부하가 심해짐
세션 (Session)
쿠키의 보안상 단점을 보완 -> How?
쿠키 기반이지만 데이터를 클라이언트가 아닌 서버
에 저장
- 클라이언트가 서버에 접속 시 세션ID를 발급 받음
- 서버는 세션ID에 해당하는 정보를 세션 저장소에 저장해둠
- 클라이언트가 서버에 요청할 때, 쿠키에 있는 세션 ID를 같이 보냄
- 서버는 세션 저장소에서 해당 세션 ID를 조회 후 저장된 데이터를 응답 시 같이 보냄
세션의 활용
- 로그인 / 로그아웃 등의 보안상 중요한 작업
세션 방식의 단점
- 데이터를 서버에 저장하므로 클라이언트가 많을수록 서버 메모리를 많이 차지함
- 많은 수의 클라이언트가 동시에 요청할 경우 서버 과부화 발생할 수 있음
JWT (Json Web Token)
단어 그대로 JSON 형식의 웹 토큰으로 JWT 토큰(Access Token)을 HTTP 헤더에 실어 서버가 클라이언트를 식별하는 방식입니다.
JWT는 JSON 데이터를 Base64Url Encoding
방식으로 인코딩하여 제공합니다.
Base 64 Encoding
의 경우 “/”와 “+”이 포함되지만 JWT는 Url에서 파라미터로 사용할 수 있도록 Url-Safe한 Base64Url Encoding
방식을 사용함
JWT 구조
https://easyhomputer.tistory.com/41
.
으로 구분하여 세 가지 정보를 인코딩하여 저장
-
Header
에는 JWT에서 사용할 타입과 해시 알고리즘의 종류가 담겨 있고, -
Payload
에는 사용자 식별 정보와 토큰 만료 기간 등이 담겨있음. 해독이 가능하므로 중요한 정보를 담는 것은 보안상 문제를 일으킬 수 있음. -
Signature
에는 헤더와 페이로드를Base64Url
로 인코딩하여 더하고,Secret Key
역시 헤더에 기록되어 있는 알고리즘으로 해시하여 값을 저장
Signature
필드로 인해 악성 유저가 Payload 값을 조작하여 보내도 Signature 값이 다르기 때문에 인증을 통과할 수 없습니다.
(Secret Key
는 흔히 쓰이는 값을 사용하면 안 되고, 매우 길고 복잡한 값을 사용하되 깃헙 등을 통해서 외부로 유출되면 안 됩니다.)
JWT 작동 방식
세션의 서버 부담을 완화 -> How?
데이터를 서버에 저장하지 않음
- 클라이언트가 서버로 인증 요청
- 인증이 성공되면 토큰을 발행하여 응답 (이 토큰은 만료 시간과 사용자를 식별할 정보 등이 기록되어 있음)
- 클라이언트는 다음 요청부터 서버에게 요청할 때 토큰을 같이 보냄
- 서버는 해당 토큰이 유효한 지 확인 후 응답
토큰에는 사용자의 비밀번호 등의 중요한 개인정보를 기록해두면 안됩니다. 사용자를 식별할 수 있는 최소한의 정보만 기록되어 있어야 합니다.
JWT의 단점
- 쿠키와 세션과 다르게
base64
인코딩을 통해서 정보를 제공하므로 전달량이 많음. (많은 수의 클라이언트가 접속할 경우 네트워크 부하가 발생할 수 있음) - 토큰이 탈취당할 경우 대처하기 곤란(불가능)합니다.