쿠키와 세션, 토큰은 HTTP 프로토콜의 특징이자 약점을 보완하기 위해 사용된다.
기본적으로 HTTP 프로토콜은 아래와 같은 특징을 가진다
HTTP는 TCP 연결을 맺고 요청(Request)를 보내면 서버는 응답(Response)을 보내고 연결을 끊어버린다. 물론 HTTP 1.1 버전은 연결을 계속 유지하는 keep-alive 옵션이 기본이긴 하다. 그러나 HTTP 1.0 버전은 기본적으로 Connectionless이다.
*HTTP 1.1 기본 옵션인 Keep-Alive 를 사용하면 하나의 TCP 연결을 여러 요청과 응답 사이에서 재사용할 수 있다. 이는 연결을 여러번 열고 닫는 비용을 줄이고, 성능을 향상시킬 수 있다는 장점을 제공한다. 그러나 각각의 요청과 응답은 여전히 독립적으로 이루어진다.
즉, 하나의 TCP 연결을 통해 여러 요청과 응답을 순서대로 주고 받을 수 있지만, 각각의 트랜잭션이 서로 의존적이거나 연속적으로 이어지는 것은 아니다.(통신쪽은 더 공부해보자)
HTTP는 상태를 따로 저장하지 않는다. 즉 연결이 끊어지는 순간 모든 상태 정보가 사라지게 된다. 따라서 서버는 클라이언트가 첫 번째 통신 때 보낸 정보를 두 번째 통신때 알 수 없다.
쿠키와 세션은 위의 두 가지 특징을 해결하기 위해 사용한다. 예를 들어 쿠키와 세션을 사용하지 않으면 로그인을 하였음에도 페이지를 이동할 때 마다 계속 로그인을 해야 한다. 그러나 쿠키와 세션을 사용하게 되면, 한번 로그인을 했을 때 어떠한 방식에 의해 그 사용자에 대한 인증이 계속 유지되게 된다.
쿠키의 동작 방식
1. 클라이언트가 페이지를 요청
2. 서버에서 쿠키를 생성해 HTTP 헤더에 쿠키를 포함시켜 응답
3. 클라이언트 브라우저의 쿠키저장소에 쿠키가 저장됨(유효기간 남으면 브라우저 종료되어도 유지됨)
4. 클라이언트가 다른 페이지에 접속할때, HTTP 헤더에 쿠키를 함께 보냄
5. 서버는 전달받은 HTTP 요청의 쿠키를 이용해 DB를 조회해 클라이언트를 식별함
세션과 비교하였을 때, 쿠키만 단독으로 사용한다면 서버에서 상태를 유지하지 않기 때문에, 클라이언트를 식별하기 위해 매번 DB를 조회해야 한다.
*만약에 쿠키가 없었다면 다시 로그인 정보를 보내야 했을 것
*서버에서 쿠키를 읽어 이전 상태 정보를 변경 할 필요가 있을 때는 쿠키를 업데이트 하여 변경된 쿠키를 HTTP 헤더에 포함시켜 응답
*브라우저의 쿠키 저장소는 사용자의 디바이스(예: PC)에 저장되며 이곳에서 관리된다. 각 브라우저는 사용자의 쿠키를 자체적으로 관리하고 저장한다. window11의 chrome 의 경우 C:\Users\your_user_name\AppData\Local\Google\Chrome\User Data\Default\Network
위치의 Cookies 파일에서 관리된다.
쿠키 사용 예시
로그인 시
로그인 후, 쿠키를 포함한 HTTP 요청
세션의 동작 방식
1. 클라이언트가 페이지를 요청
2. 서버는 해당 클라이언트를 DB에서 식별하여 세션에 저장하고, 응답으로 세션에 저장된 해당 유저 정보를 식별하는 세션 ID를 담아서 보냄
3. 클라이언트 브라우저의 쿠키저장소에 세션ID 저장됨(유효기간 남으면 브라우저 종료되어도 유지됨)
3. 클라이언트는 다음부터 요청에 세션ID 를 담아서 보냄
4. 서버는 요청에 담긴 세션 ID를 통해 세션에서 클라이언트를 식별
쿠키와 달리, 쿠키와 세션을 함께 사용하면 서버에서 상태를 유지하므로, 매번 DB를 조회할 필요가 없다. 따라서 성능적인 이점이 있다. 보안적인 측면에서도 세션은 일반적으로 안전한 방식으로 사용자 상태를 관리할 수 있다.
*스프링에서, session은 톰캣의 내장 메모리에 저장이 되므로 서버를 재시작할 때마다 세션이 초기화된다.
세션 사용 예시
로그인 시
로그인 후, 쿠키를 포함한 HTTP 요청
우리는 쿠키와 세션에 대행 알아보았고, 쿠키의 stateless 한 특징을 세션이 서버의 세션 저장소를 통해 보완할 수 있다는 것을 알게되었다. 그러나 세션에는 몇가지 문제가 존재한다.
서버는 요청마다 함께 딸려오는 세션ID를 바로바로 확인할 수 있도록 로그인한 사용자의 아이디를 메모리에 올려둔다. 메모리에 올려둔 데이터는 빠르게 확인할 수 있다는 장점이 있지만, 서버에 동시 접속하는 사용자가 많아지면 메모리 공간이 부족해져 서버에 부하가 걸리는 등의 문제가 발생한다. 따라서 메모리 공간을 많이 차지하는 세션 방식의 대안으로 토큰을 사용한다.
토큰은 다음과 갖는 특징을 갖는다.
토큰 사용 예시
단점
정리
쿠키를 통한 상태 유지에는 보완적인 측면에서 제약이 있을 수 있고, 세션은 서버 측에서 상태를 관리하면서도 일부 성능 이슈가 발생할 수 있다. 토큰은 이러한 제약을 극복하기 위해 클라이언트 측에서 인증 정보를 관리하면서도, 서버 측의 부담을 줄여준다.
자료 출처
https://code-lab1.tistory.com/298
https://interconnection.tistory.com/74
https://jhbljs92.tistory.com/entry/1-JWT-%ED%86%A0%ED%81%B0-%EC%9D%B8%EC%A6%9D%EA%B3%BC-%EC%BF%A0%ED%82%A4-%EC%84%B8%EC%85%98-%ED%86%A0%ED%81%B0
https://velog.io/@jung5318/%EC%BF%A0%ED%82%A4-%EC%84%B8%EC%85%98-%ED%86%A0%ED%81%B0%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90
https://hongong.hanbit.co.kr/%EC%99%84%EB%B2%BD-%EC%A0%95%EB%A6%AC-%EC%BF%A0%ED%82%A4-%EC%84%B8%EC%85%98-%ED%86%A0%ED%81%B0-%EC%BA%90%EC%8B%9C-%EA%B7%B8%EB%A6%AC%EA%B3%A0-cdn/