프롤로그
저번 HTTP/HTTPS 에서 HTTP 의 특징을 기억해보면
1. 비연결형(Connectionless)
클라이언트와 서버 간에 요청과 응답이 한 번 이루어 지면 연결이 끊어지고, 요청마다 새로 연결을 생성하기에 연결이 유지되지 않는다.
2. 무상태(Stateless)
서버는 클라이언트의 상태를 기억하지 않는다. 각각의 요청은 독립적으로 이루어지기에 이전 요청과는 관계가 없다.
3. 텍스트 기반 프로토콜
요청과 응답 메시지는 사람이 읽을 수 있는 텍스트 형식으로 전송된다
이렇게 있었다.
한 번 요청이 이루어지면 연결이 끊어지고 요청간에 상태를 기억하지 못하기에 이를 보완하기 위해서 추가적인 상태 유지 메커니즘이 필요하다라고 언급했었다.
2024.12.04 - [KnockOn] - [1주차 TIL] KnockOn Bootcamp HTTP/HTTPS
지금은 그 추가적인 상태유지 메커니즘에 관한 내용으로써, 쿠키, 세션, 토큰 등이 있다.
쿠키(Cookie)
쿠키란, 클라이언트(브라우저)에 저장되는 작은 데이터 조각이다. 아까 말했듯이 HTTP 프로토콜에서의 비연결형과 무상태 때문에 이를 보완하기 위해 사용되었다. 서버가 클라이언트에세 쿠키를 발급해주면, 클라이언트는 해당 쿠키를 브라우저에 저장해놓고, 서버에 요청을 보낼 때마다 자동으로 쿠키를 같이 전송한다. 서버는 클라이언트의 요청에 포함된 쿠키를 확인하여 클라이언트를 구분한다.
쉽게 예시를 들자면 중국집에서 쿠폰 나눠주고, 짜장면 시켜먹을때마다 쿠폰에 도장찍어주는 거랑 똑같다.
정리하면 그래서 쿠키는 클라이언트의 정보 기록과 상태 정보를 표현하는 용도로 사용한다.
정보기록이란, 흔히 생각하면 "다시 보지 않기", "7일간 표시하지않기" 등의 팝업 옵션을 기억하기 위하여 쿠키에 저장해놓고, 이를 통해서 팝업 창 표시 여부를 판단한다. 상태정보는 회원 가입과 로그인을 통해서 개개인에게 맞춤형 서비스를 이용한다. 그러기 위해서 클라이언트를 식별해야하는데, 이 또한 쿠키에 저장해서 사용한다.
사용자 식별하고 트래킹 및 분석한다.
쿠키가 없었다면, 사용자의 정보를 알지 못해서 이전에 로그인을 했었더라도, 정보가 남아있지 않아서 로그인한 상태에서 값을 요구해도 정보를 받아올 수없었다. 그러나 쿠키덕에 이제 그게 가능해졌다.
결론적으로 쿠키가 사용되는 이유는 상태 유지, 웹 트레픽 최적화(불필요한 데이터 전송 감소), 광범위한 지원이 되겠고, 단점이 있다면 보안 문제(누군가가 쿠키를 탈취해서 쓴다면...), 데이커 크기의 제한(4KB 저장 용량 제한), 서드파티 쿠키로 인한 사용자 추적 및 데이터 유출때문에 프라이버시 문제가 생긴다.
쿠키의 구조
쿠키는 키-값 쌍으로 구성된다.
자바로 쿠키를 만들때 이렇게 "Cookie" 밸류에 "키=값;키=값") 이렇게 구성을 했었다.
실제 gajai.com 사이트를 가서 헤더를 살펴보면
쿠키가 이런식으로 구성되어있는 것을 확인할 수 있다.
근데 좀 이상한 단어들로 막 적혀있는데, 조금 이따가 알아보고, 쿠키마다 구분하기 위해서 ;로 구분되는 것을 확인할 수 있다. 쿠키는 일단 다음과 같은 속성을 포함해야하는데,
개발자도구 -> Application -> Cookies 칸에 가보면 저렇게 쿠키들이 설정되어있는 것이 보일 것이다.
그중 위쪽에 보면
Name, Value, Domain, Path, Expires, Size, HttpOnly, Secure, SameSite, Patrion Site Key, Cross Site, Priority 이렇게 있는 것을 확인할 수 있다.
쿠키는 여러 속성을 포함하게 되는데, 그게 위의 저것들이다.
1) Name
쿠키의 이름. 클라이언트와 서버간 쿠키를 식별하는데 사용한다. 같은 도메인 내에서 동일 이름의 쿠키가 중복사용이 불가능하다.
2) Value
쿠키의 값이다. 서버가 클라이언트에 저장한 데이터이다. 세션ID, 사용자 고유 식별자, 기타 데이터 등이 들어가있다.
3) Domain
쿠키가 유효한 도메인을 나타낸다. 해당 도메인과 서브도메인에서만 쿠키가 유효하고, 다른 도메인은 사용이 불가능하다.
4) Path
쿠키가 유효한 URL 경로를 지정한다. 지정된 경로에서만 쿠키가 전송되며, 일반적으로 보통 / 로 설정한다.
5) Expires or Max-Age
쿠키의 만료 시간을 나타낸다. 이 지정된 시간이 끝나면 자동으로 삭제된다.
6) Size
쿠키의 크기이다. 단, 쿠키는 4KB을 초과할 수 없다.
7) HttpOnly
자바스크립트에서 보통 document.cookie; 를 치면 쿠키를 획득할 수 있다.
위와 같이 말이다. 저것을 방지하는 역할이다. 그래서 쿠키탈취를 막는다.
8) Secure
쿠키가 HTTPS 연결에서만 전송될 수 있는지 여부를 나타낸다. 그리고 암호화하지 않은 HTTP 연결에서는 쿠키가 전송되지 않게 보장한다.
9) SameSite
교차 사이트 요청에서 쿠키의 전송을 제한하는 옵션이다.
Strict : 동일 사이트에서만,
Lax : GET요청 및 일부 안전한 요청에서만
None : 모든 요청에서 (secure 필요)
10) Partioned
특정 브라우저에서 독립적으로 격리된 쿠키 여부를 알려준다.
11) Cross Site
해당 쿠키가 교차 사이트 요청에서 어떻게 작동하는가?
12) Priority
쿠키의 우선순위. Low, Medium, High 중요도가 있다.
정리를 하자면
- 필수 속성: Name, Value (쿠키의 이름과 값).
- 보안 강화 속성: Secure, HttpOnly, SameSite.
- 유효 범위 설정: Domain, Path, Expires.
이렇게 된다.
세션(session)
아까 쿠키가 중국집 쿠폰 나눠준거랑 똑같다고 보면 된다고 했다. 근데
기철이마냥 저렇게 도장 하나 가지고서 뭘 한다면..
탈취한 사람 마음대로 할 수 있는 것이다.
저것을 막기 위해서 나온 게 세션이다. 인증 정보를 서버에 저장하고, 해당 데이터에 접근할 수 있는 키(유추할 수 없는 랜덤한 문자열)을 만들어 클라이언트에 전달한다. 이 키를 보통 Session ID라고 한다.
흔히 카페 키오스크에 스탬프 입력하는 것을 생각해보자. 번호는 바꿔서 입력할 수는 있어도, 내부 사용자의 스탬프 개수는 건들 수가 없다. 기록된 내역은 조작할 수 없게 되는 것이다. 즉, 클라이언트가 인증 정보를 변조할 수 없게 하기 위한 방식이 세션방식이다. 브라우저는 해당 키를 쿠키에 저장하고 이후에 HTTP 요청을 보낼 때 사용한다.서버는 요청에 포함된 키에 해당하는 데이터를 가져와 인증 상태를 확인한다.
세션의 특징으로
1. 서버에서 관리
세션 데이터는 서버의 메모리나 데이터베이스에 저장되고, 클라이언트에는 세션을 식별할 수 있는 고유 ID만 전달
2. 클라이언트 식별
쿠키 또는 URL파라미터 또는 HTTP 헤더로 서버로 전송
3. 일시적 저장
브라우저가 종료되거나 일정 시간 지나면 삭제, 이 유효기간은 서버에서 설정
4. 보안성
클라이언트 측 저장소에서 쿠키 보관하는 것보단 보안이 높다.
이렇다 보니까, 보안성이 쿠키보다는 좋아진다. 그리고 서버에서 데이터를 중앙에서 관리할 수 있으므로 복잡한 상태 관리가 가능하다. 다만, 그러다보니까 서버의 부담이 증가하고, 확장성에 문제가 생기고, 속도가 저하될 수 있다.
구분 | 쿠키 | 세션 |
초기 목적 | HTTP의 무상태성을 보완하고, 클라이언트 상태를 유지. | 서버에서 사용자 상태를 관리하고 인증, 데이터 저장. |
발전 과정 | 1990년대: Netscape에서 개발 → 보안 속성 추가 → 트래킹 쿠키 논란 | 1990년대: 세션 ID 도입 → 서버 스토리지 개선 → 분산 환경 지원 |
현대적 기술 | 쿠키 보안 강화(SameSite, Secure, HttpOnly). | Redis, JWT와 같은 대체 기술 등장. |
토큰(Token)
토큰은 클라이언트와 서버 간의 인증, 권한 부여, 데이터 교환을 위해 사용되는 데이터의 작은 단위이다. 주로 문자열 형태로 되어있으며, 고유한 식별 정보를 포함하고 있는데, 주로 인증과 인가, 상태유지를 위해서 사용된다.
주로 로그인 인증, API 호출 인증, 권한 관리 등이 있는데, JWT, OAuth Token등 다양한 유형이 있다. Stateless(HTTP의 특징중 하나) 환경에서 되게 유용하다.
토큰을 사용하게 되면 서버가 상태를 저장하지 않고 사용자에게 정보를 다 넘겨주기 때문에 확장성과 성능이 우수하다. 그리고 토큰 자체에 데이터가 있기 때문에 별도의 서버 조회가 필요가 없다.
암호화를 통해 데이터의 무결성과 기밀성을 보장하기에 보안성이 좋고, 여러군대에서 그래서 사용중이다.
다만, 문제로는 토큰이 탈취되면 답이 없어지기에, 만료시간을 설정하거나, Refresh Token등을 사용한다. 토큰이 만료되면 새로 발급받아야하고, 이를 처리하는 추가적인 로직이 필요하다.
구분 | 토큰 | 세션 |
저장 위치 | 클라이언트(브라우저, 앱 등) | 서버 |
확장성 | Stateless(서버 확장에 유리) | Stateful(확장성 낮음) |
보안 | 클라이언트에 저장되므로 관리 필요 | 서버에 저장되므로 보안성이 더 높음 |
데이터 크기 | 클라이언트에서 전송하므로 크기가 문제될 수 있음 | 서버 저장으로 인해 클라이언트 부담 적음 |
JWT(Json Web Token)
JWT는 Json 기반의 토큰으로, 클라이언트와 서버 간의 테이터 교환 및 인증을 위해 사용되는 인증 토큰이다. 클라이언트가 서버에 요청할 때 자기 자신을 증명하는 데 사용된다. Stateless(상태 비저장) 인증 방식으로 서버가 상태 정보를 저장하지 않아도 되며, 확장성과 효율성이 뛰어난다.
설명은 아래 그림들로 요약이 되어있으니, 저걸로 대체하겠다.
브라우저 저장소
브라우저 저장소란, 웹 브라우저가 제공하는 클라이언트 측 데이터 저장소이다. 아까 쿠키, 토큰 이런 거 클라이언트 쪽에서 저장하고 있어야하는데, 그런 개념이라고 보면 된다. 서버와의 통신 없이 클라이언트 측에서 데이터를 저장하고 관리한다.
1. 쿠키
서버와 클라이언트 간의 상태 정보를 저장한다. 로그인 상태 유지, 세션 ID저장에 사용된다.
4KB 데이터 크기 제한이 있고, 만료 시간 설정이 가능하다.
2. 로컬 스토리지
브라우저가 종료되어도 영구적으로 데이터 저장이 된다. 서버와 통신하지 않고 클라이언트 데이터를 관리한다.
데이터 용량은 5MB(브라우저마자 다름), 키-값 형태로 데이터 저장이 된다. 동일 도메인에서만 접근이 가능하다.
다크모드 설정, 언어 선택 등 사용자 환경 설정을 저장하고, 장바구니 데이터 유지에서도 사용한다.
3. 세션 스토리지
브라우저가 종료되면 사라진다. 또는 새로고침해도 사라진다.
데이터 용량은 5MB, 키-값 형태로 데이터 저장이 된다. 동일 도메인에서만 접근이 가능하다.
로그인 상태 유지(현재 탭 동안만), 양식 입력 데이터 임시 저장 등에 사용된다.
4. 인덱스드 DB
브라우저에서 지원하는 비관계형 데이터베이스이다. 대용량을 효율적으로 관리하며, 트랜젝션과 비동기 작업을 지원한다. GB단위이며, 객체로 저장한다. 키-값 기반이다.
브라우저 게임 데이터 , 오프라인 메모 앱 등에서 쓰인다.
5. 서비스 워커 캐시
오프라인 지원 및 네트워크 요청 캐싱을 위해 사용된다. PWA에서 주로 사용한다.HTTP요청에 대한 응답 데이터를 저장한다. 정적 리소스 캐싱할 때 쓰인다.
- 짧은 수명, 현재 탭에만 필요한 데이터: 세션 스토리지.
- 영구적으로 유지해야 하는 작은 데이터: 로컬 스토리지.
- 서버와 동기화가 필요한 인증 정보: 쿠키.
- 대규모 데이터, 구조화된 저장: 인덱스드DB.
- 오프라인 상태 지원, 정적 파일 캐싱: 서비스 워커 캐시.
도전
네이버 접속시 사용되는 쿠키 확인해보자.
초기 이렇게 되어있었는데 로그인을 해보겠다.
뭔가 쿠키값이 들어났다.
모든 값을 1로 변경해보고 새로고침 하면
로그인이 풀려버린다!
에필로그
이번에도 이리 길어질 줄 몰랐다.
'KnockOn' 카테고리의 다른 글
[1주차 TIL] KnockOn Bootcamp 프록시 (1) | 2024.12.07 |
---|---|
[1주차 TIL] KnockOn Bootcamp 패킷 (1) | 2024.12.06 |
[1주차 TIL] KnockOn Bootcamp HTTP/HTTPS (2) | 2024.12.04 |
[1주차 TIL] KnockOn Bootcamp 프로토콜, OSI, TCP, UDP (0) | 2024.12.03 |
[1주차 TIL] KnockOn Bootcamp 웹이란? (4) | 2024.12.02 |