HTTP의 특징, 쿠키와 세션, 토큰

Hyun·2024년 1월 24일
0

기본 지식

목록 보기
1/3

쿠키와 세션, 토큰은 HTTP 프로토콜의 특징이자 약점을 보완하기 위해 사용된다.
기본적으로 HTTP 프로토콜은 아래와 같은 특징을 가진다

1. Connectionless(비연결성)

HTTP는 TCP 연결을 맺고 요청(Request)를 보내면 서버는 응답(Response)을 보내고 연결을 끊어버린다. 물론 HTTP 1.1 버전은 연결을 계속 유지하는 keep-alive 옵션이 기본이긴 하다. 그러나 HTTP 1.0 버전은 기본적으로 Connectionless이다.

*HTTP 1.1 기본 옵션인 Keep-Alive 를 사용하면 하나의 TCP 연결을 여러 요청과 응답 사이에서 재사용할 수 있다. 이는 연결을 여러번 열고 닫는 비용을 줄이고, 성능을 향상시킬 수 있다는 장점을 제공한다. 그러나 각각의 요청과 응답은 여전히 독립적으로 이루어진다.

즉, 하나의 TCP 연결을 통해 여러 요청과 응답을 순서대로 주고 받을 수 있지만, 각각의 트랜잭션이 서로 의존적이거나 연속적으로 이어지는 것은 아니다.(통신쪽은 더 공부해보자)

2. Stateless(무상태)

HTTP는 상태를 따로 저장하지 않는다. 즉 연결이 끊어지는 순간 모든 상태 정보가 사라지게 된다. 따라서 서버는 클라이언트가 첫 번째 통신 때 보낸 정보를 두 번째 통신때 알 수 없다.

쿠키와 세션은 위의 두 가지 특징을 해결하기 위해 사용한다. 예를 들어 쿠키와 세션을 사용하지 않으면 로그인을 하였음에도 페이지를 이동할 때 마다 계속 로그인을 해야 한다. 그러나 쿠키와 세션을 사용하게 되면, 한번 로그인을 했을 때 어떠한 방식에 의해 그 사용자에 대한 인증이 계속 유지되게 된다.

🍪 쿠키(Cookie)

  • 쿠키는 클라이언트(브라우저) 로컬에 저장되는 키와 값이 들어있는 작은 데이터 파일이다.
  • 사용자 인증이 유효한 시간을 명시할 수 있으며, 유효 시간이 정해지면 브라우저가 종료되어도 인증이 유지된다.
  • 쿠키는 클라이언트 상태 정보를 로컬에 저장했다가 참조한다.
  • 클라이언트에 최대 300개의 쿠키 저장 가능, 하나의 도메인당 최대 20개의 쿠키값을 가질 수 있다. 하나의 쿠키 크기는 최대 4KB이다.
  • 서버에서 Response을 보낼 때 Response Header에 Set-Cookie 속성을 사용하면 클라이언트에 쿠키를 생성할 수 있다.
  • 쿠키는 사용자가 따로 요청하지 않아도 브라우저가 Request 시에 Request Header를 넣어서 자동으로 서버에 전송한다.

쿠키의 동작 방식
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 요청

📅 세션(Session)

  • 세션은 쿠키를 기반하고 있지만, 사용자 정보 파일을 브라우저에 저장하는 쿠키와 달리, 세션은 사용자 정보 파일을 서버측에서 관리한다.
  • 브라우저에서는 세션 ID만 쿠키로 가지고 있다.
  • 서버에서는 클라이언트를 구분하기 위해 세션 ID를 부여하며, 웹 브라우저가 서버에 접속해서 브라우저를 종료할 때까지 인증상태를 유지한다.
  • 물론 접속 시간에 제한을 두어 일정 시간 응답이 없다면 정보가 유지되지 않도록 설정이 가능하다
  • 사용자에 대한 정보를 서버에 두기 때문에(클라이언트엔 세션 ID만 둔다), 쿠키보다 보안이 좋지만, 사용자가 많아질수록 서버 메모리를 많이 차지하게 된다.
  • 클라이언트가 Request 를 보내면, 해당 서버가 클라이언트에게 쿠키로 유일한 ID를 전달하는데 이것이 세션 ID이다.

세션의 동작 방식
1. 클라이언트가 페이지를 요청
2. 서버는 해당 클라이언트를 DB에서 식별하여 세션에 저장하고, 응답으로 세션에 저장된 해당 유저 정보를 식별하는 세션 ID를 담아서 보냄
3. 클라이언트 브라우저의 쿠키저장소에 세션ID 저장됨(유효기간 남으면 브라우저 종료되어도 유지됨)
3. 클라이언트는 다음부터 요청에 세션ID 를 담아서 보냄
4. 서버는 요청에 담긴 세션 ID를 통해 세션에서 클라이언트를 식별

쿠키와 달리, 쿠키와 세션을 함께 사용하면 서버에서 상태를 유지하므로, 매번 DB를 조회할 필요가 없다. 따라서 성능적인 이점이 있다. 보안적인 측면에서도 세션은 일반적으로 안전한 방식으로 사용자 상태를 관리할 수 있다.

*스프링에서, session은 톰캣의 내장 메모리에 저장이 되므로 서버를 재시작할 때마다 세션이 초기화된다.

세션 사용 예시
로그인 시

로그인 후, 쿠키를 포함한 HTTP 요청

🪙 토큰(Token)

우리는 쿠키와 세션에 대행 알아보았고, 쿠키의 stateless 한 특징을 세션이 서버의 세션 저장소를 통해 보완할 수 있다는 것을 알게되었다. 그러나 세션에는 몇가지 문제가 존재한다.

서버는 요청마다 함께 딸려오는 세션ID를 바로바로 확인할 수 있도록 로그인한 사용자의 아이디를 메모리에 올려둔다. 메모리에 올려둔 데이터는 빠르게 확인할 수 있다는 장점이 있지만, 서버에 동시 접속하는 사용자가 많아지면 메모리 공간이 부족해져 서버에 부하가 걸리는 등의 문제가 발생한다. 따라서 메모리 공간을 많이 차지하는 세션 방식의 대안으로 토큰을 사용한다.

토큰은 다음과 갖는 특징을 갖는다.

  • 토큰에는 특수한 수학적 원리가 적용되어 있어 마치 위조 방지 장치가 있는 지폐처럼 해당 서버만이 유효한 토큰을 발행할 수 있다.
  • 토큰 자체가 인증을 위한 정보를 포함하고 있기 때문에, 서버 측에서 따로 토큰과 관련된 정보를 저장할 필요가 없다. 토큰에는 클라이언트나 서버가 필요로 하는 인증, 권한 부여, 사용자 정보 등이 이미 포함되어 있다.
    => 따라서 클라이언트가 토큰을 받아서 쿠키나 스토리지에 저장한 후, 필요할 때마다 요청 헤더에 토큰을 포함시켜 제시하면 서버는 메모리에 토큰 정보를 따로 저장할 필요 없이 자기가 발급한 토큰임을 알아보고 사용자의 요청을 허가한다.
  • 따라서 stateless 하다.

토큰 사용 예시

단점

  • 쿠키, 세션과는 다르게 토큰 자체의 데이터 길이가 길기 때문에 인증 요청이 많아질수록 네트워크 부하가 심해질 수 있다.
  • Payload 자체는 조회가 가능하기 때문에 유저의 중요한 정보를 담을 수 없다.
  • 토큰은 발급하면 만료될 때까지 계속 사용이 가능하기 때문에 토큰이 탈취당하면 대처하기 어렵다.

정리
쿠키를 통한 상태 유지에는 보완적인 측면에서 제약이 있을 수 있고, 세션은 서버 측에서 상태를 관리하면서도 일부 성능 이슈가 발생할 수 있다. 토큰은 이러한 제약을 극복하기 위해 클라이언트 측에서 인증 정보를 관리하면서도, 서버 측의 부담을 줄여준다.

자료 출처
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/

profile
better than yesterday

0개의 댓글