세션, 쿠키, 토큰, 캐시를 사용하는 이유
HTTP 프로토콜의 connectionless, stateless의 특징 때문이다.
connectionless
클라이언트가 서버에 요청을 보내면 서버는 응답을 보내고 즉시 연결을 끊는다. 즉, 한번의 요청 이후 클라이언트와 서버의 연결이 지속되지 않는다. 이러한 이유는 여러 클라이언트와 서버간의 접속을 원활하게 하기 위해서다.
keep-alive
연결을 지속하기 위해선 HTTP request header에 keep-alive라는 값을 추가하여 timeout, max의 옵션을 설정하는 방법이 있다. timeout의 시간동안 혹은 max번의 횟수만큼 연결이 지속된다.
- 장점 : 데이터를 계속 주고 받아야할 때 연결비용 감소
- 단점 : 사용자가 많은 경우 새로운 사용자를 수용할 수 없는 경우 발생
stateless
HTTP는 통신이 끝나면 이전 상태를 유지하지 않는다. 이러한 특징 때문에 매번 서버에 요청을 보낼 때마다 로그인 여부를 확인하는 요청을 보내야한다.
이러한 특성을 보완하고자 쿠키와 세션이 등장했다.
1. 쿠키
브라우저에 저장되는 정보
쿠키는 브라우저에 저장되는 작은 텍스트 조각이다.
특징
- 제 3자도 조회 가능하기 때문에 보안상 민감한 정보를 저장하는 것은 부적합
- 만료일 지정 가능
- 웹 브라우저에 key : value로 저장
- 용량 제한이 있어 많은 정보를 담을 수 없음
- 쿠키의 사이즈가 커지면 네트워크에 부하가 심해짐
구성요소
- 이름 : 쿠키를 구별하는 데 사용되는 이름
- 값 : 해당 쿠키의 값
- 유효시간 : 유지시간
- 도메인 : 쿠키를 전송할 도메인
- 경로 : 쿠키를 전송할 요청 경로
쿠키의 동작 방식
- 클라이언트가 페이지를 요청
- 서버가 쿠키 생성
- 서버에서 HTTP header에 쿠키를 담아 응답
- 브라우저가 종료되어도 쿠키의 유효 시간이 남아있다면 클라이언트에서 해당 쿠키를 보관
- 이전에 저장된 쿠키와 동일한 요청을 할 경우 이미 존재하고 있는 쿠키를 HTTP header에 담아 요청
- 서버에서 HTTP header에 담긴 쿠키를 읽어 상태를 변경할 필요가 있을 때 변경사항을 쿠키에 반영하여 HTTP header에 담아 응답
예시
- 로그인 시 브라우저에 아이디와 비밀번호를 저장
- 쇼핑몰 장바구니
- 자동로그인
- 팝업에서 “오늘 더 이상 보지 않음” 체쿠
2. 세션
서버에 저장되는 정보
stateless
사용자를 기억하지 못하는 서버
세션아이디를 통해 로그인된 사용자를 알아보는 서버
특징
- 쿠키보다 상대적으로 안전
- 브라우저를 닫거나 서버에서 세션을 삭제하면 없어짐
- 하지만, 해커가 세션ID를 탈취하여 클라이언트인 척 위장 가능
- 저장데이터에 제한이 없음
- 유저가 접속할 때 부여되는 세션 ID를 사용해 사용자를 구분
- 사용자의 수만큼 메모리를 차지함
세션/쿠키 기반 인증 방식 (서버 기반)
- 사용자가 로그인하며 로그인 정보를 서버에 전송
- 로그인에 성공하면 사용자에 고유한 세션 ID를 생성하여 클라이언트에 전달
- 클라이언트는 세션 ID를 쿠키에 저장하고 서버에 요청시 쿠키를 요청의 헤더에 담아 전송
- 서버는 전달받은 쿠키를 사용하여 세션 ID가 유효한지 확인하고 클라이언트를 구분
세션 vs 쿠키
세션과 쿠키는 같이 사용하는 것이 좋다.
3. 토큰
세션과 또 다른 로그인 유지 방식
특징
- 난수 형태의 문자열
- access token을 가장 많이 사용
- 메모리에 저장해놓지 않고도 서버는 토큰을 알아볼 수 있음
- 서버가 강제로 유저를 로그아웃 시키는 것이 불가능
- 한 번 발행한 토큰은 유효기간이 끝날 때까지 따로 통제할 수 없어 탈취당할 가능성이 높음
- 만료기간을 짧게 지정하면 이를 보완할 수 있음
1) JWT 기반 인증
- JWT(Json Web Token)이란 인증에 필요한 정보들을 암호화시킨 토큰
- 쿠키/세션 방식과 유사하게 JWT 토큰(Access Token)을 HTTP 헤더에 담아 서버가 클라이언트를 식별함
JWT 구조
- header : JWT인 토큰의 유형이나 HMAC SHA256 또는 RSA와 같이 사용되는 해시 알고리즘 중 무엇으로 사용했는지 등의 정보를 담는다.
- payload : 토큰에 담을 정보, 클라이언트에 대한 정보나 메타 데이터가 담긴다.
- signature : 헤더에 지정한 알고리즘과 secret 키, 서명으로 payload와 header를 담는다.
예시
- header
-
암호화할 해싱 알고리즘 및 토큰 타입을 지정
- payload
-
토큰에 담을 정보
-
클라이언트의 고유 ID 혹은 유효기간 등
-
kay-value 형식을 Claim이라 함
- signature
동작과정
- 서버에 토큰이 저장되는 것이 아니라 클라이언트가 필요한 정보를 토큰에 담아서 요청시 함께 담아 보낸다.
- 서버는 요청이 오면 토큰을 검증하고 해당 요청을 처리
- 사용자가 로그인시 로그인 정보를 서버에 전달
- 로그인에 성공하면 서버는 사용자 식별 정보를 body에 담아 토큰을 발급하고 클라이언트에 전달
- 클라이언트는 전달받은 토큰을 쿠키나 로컬/세션 스토리지에 저장하고 이후 서버에 요청시 해당 토큰을 담아 전달
- 서버는 요청을 받을 때 토큰을 검증하고 요청을 처리한다.
장점
- Header와 Payload를 가지고 Signature를 생성하므로 데이터위변조를 막을 수 있다.
- 인증 정보에 대한 별도의 저장소가 필요없다.
단점
- JWT는 토큰의 길이가 길어, 인증 요청이 많아지면 네트워크 부하가 심해진다.
- Payload 자체는 암호화되지 않기 떄문에 중요한 정보는 담을 수 없다.
- 토큰은 한 번 발급되면 유효기간이 만료될 때까지 계속 사용 가능하기 때문에 토큰을 탈취당하면 대처하기 어렵다.
세션 vs 토큰 인증
4. 캐시
자주 사용하는 데이터나 값을 미리 복사해놓는 임시 저장소
- 반복적으로 데이터를 불러오는 경우 메모리에 데이터를 저장해놓고 필요할 때 불러다 슴
- 데이터를 저장해놨다가 다시 사용할 때 꺼내 사용해 서버에 데이터 전송을 요청할 필요가 없음
- 인터넷 환경 뿐만아니라 컴퓨터 하드웨어에도 CPU 캐시 등이 존재