쿠키와 세션을 사용하는 이유
HTTP 통신은 기본적으로 stateless(상태를 유지하지 않음) 한 특징 때문에 요청이 오면 그에 맞는 응답을 하고
연결을 끊어버린다 그래서 서버 입장에서는 클라이언트를 구분하기 위해 서로를 식별할 수 있는 데이터가 필요했고
로그인과 같은 일을 할 때, '누가' 로그인 중인지 상태를 기억하기 위해 쿠키, 세션, 토큰을 사용한다
쿠키
쿠키는 유효기간이 있고 키-벨류의 형태로 브라우저에 저장된다
서버에서 쿠키가 오면 브라우저는 쿠키를 저장해뒀다가 다음에 요청할 때마다 쿠키를 HTTP 해더에 동봉해서 보낸다
서버는 요청에 들어 있는 쿠키를 읽어서 사용자가 누구인지 파악하는 형식이다

브라우저는 쿠키가 있다면 자동으로 동봉해서 보내주므로 따로 처리할 필요가 없다

크롬 개발자탭에서 확인 가능
위의 사진처럼 외부에 노출되어있기 때문에 민감한 정보를 넣어서는 절대 안된다
쿠키의 단점
- 외부에 노출되어있고 쿠키가 조작될 수 있어 보안에 취약
- 쿠키에는 용량 제한이 있어 많은 정보를 담을 수 없다
세션
쿠키의 보안적인 단점을 해결하기 위해 민감한 정보는 서버측에서 관리하는 방식이다.
쿠키는 브라우저에 저장, 세션은 서버(메모리)에 저장되는 것
서버는 사용자를 식별할 수 있는 고유한 값(sessionID)과 비밀 키로 서명된 값을 쿠키에 담아서 보내주고 요청이 들어오면 내 서버에서 발급된 쿠키인지 비밀 키를 통해 유효성 검사를 한다.
즉 세션은 쿠키가 존재해야 세션도 존재할 수 있다
브라우저에 저장된 세션 쿠키

서버에서 쿠키의 세션 ID로 조회되는 세션

세션의 단점
- 해커가 비밀 키로 서명된 세션Id 자체를 탈취하여 클라이언트인척 위장할 수 있다.
- 서비스가 떡상해서 사용자들이 엄청나게 많은 숫자로 늘어나게되면(저장되는 세션이 많아짐 => 한정된 메모리 용량 문제 발생) 운영자는 서버를 하나 더 증설하게 되는데 서버 끼리 메모리 공유는 불가능 하기에 세션 정보들을 공유할 수 없다. (세션을 db에 저장하게 되면 성능이 저하되기 때문에 Redis 메모리 서버를 세션 저장용으로 사용하기도 한다)
토큰
위의 쿠키와 세션의 문제점을 보완하기 위해 나온것이 JWT(JSON Web Token) 토큰이다.
JWT는 쿠키, 세션 방식에서 비밀키를 통해 내 서버에서 발급한 것을 증명하는건 똑같지만
클라이언트에 대한 정보는 토큰에 들어있어 서버에서는 세션을 유지하지 않아도 되고 세션을 관리해야했던 부담을 줄여줄 수 있다

JWT는 위의 사진처럼 .을 기준으로 Header, Payload, Signature 세가지로 나뉜 base64로 인코딩 문자열의 조합이다
클라이언트의 정보를 담는 Payload부분은 base64로 디코딩시 그대로 복호화가 가능하므로 민김한 정보는 절대로 저장하지 않아야 한다
JWT 인증방식
- 사용자가 로그인시 서버에서는 계정 정보를 읽어 사용자를 확인 후, 사용자 고유ID값을 부여한 후,
기타 정보와 함께 Payload에 넣는다. - 암호화할 비밀 키를 이용하여 Access Token을 발급 한다.
- 클라이언트는 브라우저에 쿠키 또는 로컬스토리지에 토큰을 저장한다.
- 서버에 인증이 필요한 요청마다 HTTP 헤더에 토큰을 실어서 보낸다.
- 서버는 토큰을 받으면 토근의 Signature 부분을 비밀 키로 복호화 후 조작 여부, 유효 기간을 확인한다.
- 유효성 검사가 완료되면 클라이언트 정보가 담긴 Payload 부분을 참고하여 사용자에 맞는 데이터를 가져온다
JWT 단점
- 한번 발급된 JWT는 유효 기간이 만료될때까지 계속 사용 가능하기 때문에 탈취당하게 되면 악용될 수 있다.
- 세션을 이용하면 PC로 로그인했다가 모바일로 로그인시 PC는 로그아웃을 시키는 등 클라이언트를 관리할 수 있지만 JWT 토큰은 서버에서 클라이언트를 관리 할 수 없다.
세션 방식과 토큰 방식은 각각 장단점이 있으므로 현재 프로젝트의 상황에 맞는 방식을 선택하도록 하자!
'이것저것' 카테고리의 다른 글
| AI 응답 속도 개선하기 (2) | 2024.08.21 |
|---|---|
| 동적 객체 생성 vs 정적 객체 생성 (0) | 2024.04.30 |
| 다마고치 응가 기능 어떻게 구현하지 (0) | 2024.04.24 |
| webpack 개념과 탄생 배경 (0) | 2024.03.21 |
| tsc, babel 차이점 (0) | 2024.03.19 |