![[Web Security/Security] Cookie vs Session vs Token](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs9ggw%2FbtsIle188je%2F4n20s9PE8jFx9qjN5r20k1%2Fimg.gif)

웹 인의 대표적 방법 3가지를 알아보자
장단점까지 알고 있다면 더 좋고 왜 토큰 방식을 많이 사용하는지 알아보자
결론은 무상태성, 보안성, 유연성, 편의선에서 토큰이 더 편하다.
Cookie
Key-Value의 문자열로 구성된다.
클라이언트가 어떤 도메인을 방문하게 되면 클라이언트에 작성되는 파일이다. 즉 정보를 모든 정보를 라이언트가 관리한다.

요약하자면 다음과 같은 동작 순서를 가진다.
- client가 server에 request를 보낸다.
- server는 client 측이 가지고 있었으면 하는 정보를 응답 헤더의 Set-Cookie에 담는다.
- 이후 해당 client는 요청을 보낼 때마다, 매번 저장된 쿠키를 요청 헤더의 Cookie에 담아 보낸다
이를 통해서 server는 클라이언트를 식별할 수 있다.
장점
- 클라이언트 측 저장
서버측에 저장을 한하니 서버의 리소스를 절약할 수 있다. - 자동 전송
브라우저는 자동으로 쿠키를 서버에 전송함으로 개발자가 별도의 쿠키를 전송하는 코드를 작성할 필요 없다. - 브라우저 지원
거의 대부분의 브라우저가 쿠키를 지원함으로 추가 설정 없이 대부분 사용자에게 적용할 수 있다.
단점
- 보안에 취약함
요청시 쿠키의 값 그대로를 보내기 때문에 유츌 및 조작에 당할 위험이 크다. - 용량 제한이 있어서 많은 정보를 담을 수 없음
4MB - 쿠키 사이즈가 커지면 부하가 커짐
항상 요청하고 요청 받기 때문에 통신량이 늘어날 수 있다.
Session
쿠키의 보안이슈 때문에 쿠키에 민감한 정보를 담을 수 없으니 민감한 정보(ex 비밀번호)등은 브라우저가 아닌 민감한 정보를 서버가 관리하는 방법
서버의 메모리(redis)혹은 로컬 파일, 데이터베이스에 저장한다.
세션인증 방식도 쿠키를 사용한다.

요약하면 다음과 같은 동작 순서를 가진다.
- 유저가 로그인하면 세션이 session Id를 기준으로 저장된다.
- 서버가 쿠키를 생성하고 쿠키안에 Session Id를 저장한다.
- Response헤더에 Session Id가 담긴 쿠키를 client에게 보내준다.
- client는 요청을 보낼때 마다 항상 Session Id가 담긴 쿠키를 전송한다.
- 쿠키에 담긴 Session Id를 통해서 server는 인증을 수행한다.
장점
- 보안성
민감한 정보를 서버쪽에 저장함으로써 민감한데이터가 client에 노출되지 않는다. - 세션 만료
server의 세션에 유효 기간을 설정할 수 있어서, 일정 시간동안 활동이 없으면 세션을 종료하도록 해 보안성을 추가로 확보할 수 있다. - 유연성
세션 데이터는 다양한 형태의 데이터를 저장할 수 있다. 예를 들면 사용자 정보, 권한, 상태 등이 있다.
단점
- 여전한 탈취 가능성
클라이언트에 민감한 정보가 안간다고 해서 탈취가 안되는 것은 아니다.
공격자가 쿠키안의 세션 Id를 탈취해서 클라이언트인척 공격할 수 있다. - 서버 부하
세션은 메모리에 많이 저장된다. 따라서 사용자가 많아지거나 정보를 많이 담게 되면 서버의 메모리 자원을 많이 잡아 먹는다.
또한 세션 정보를 조회해야하는 오버헤드가 발생한다. (DB는 조회하면 조회할 수록 손해다.) - Stateless 하지 않다
사용자의 정보를 저장해 놔야하기 때문에 무상태성에 반하며 RESTFULL한 서비스를 만들었다 할 수 없다.
Token
세션에서는 쿠키에 sessionId값을 직접 담아서 보냈다면 Token은 암호화된 Token을 보내준다.
세션은 세션정보를 가지고있어서 Id값을 통해서 정보를 조회해야하는 오버헤드가 발생한다.
이를 보환하기 위해서 서버메모리에 사용자 정보를 저장하는 것이 아니라 클라이언트측에 암호화해서 저장한다.
웹에서는 쿠키, 세션이 있지만 앱에서는 없기 때문에 앱에서 많이 사용된다.

요약하자면 다음과 같은 방식을 따른다.
- client가 아이디와 비밀번호로 로그인을 한다.
- 서버 측에서 토큰을 발급하고 client에게 준다.
- client는 서버 측에서 전달 받은 토큰을 쿠키 혹은 local storage에 저장한다.
- 저장한 Token을 요청할 때마다 HTTP헤더에 담긴 토큰이 자동으로 보내진다.
- server에서 받은 Token에는 사용자의 정보가 담겨있어 DB를 조회하지 않고 누가 요청하는지 알 수 있다.
장점
- 무상태성
토큰은 클라이언트 측에 저장됨으로 Stateless하다 할 수 있으며 session이 저장된 서버에서만 볼 수 있는 것이 아니라 다른 서버에서도 인증을 할 수 있다. - CORS 문제에 도움이 됨
CORS란 브라우저가 오리진이 다른 요청을 차단하는 것이다.(나중에 자세히 다루겠다)
토큰은 이때 CORS정책을 추가해서 특정 오리진에서의 요청을 허용할 수 있어서 문제를 해결하는데 도움이 된다. - DB사용을 줄임
이는 서버의 부하, 비용을 줄일 수 있다. - 서명
통신중에 토큰 값이 변경 혹은 오염됐는지 알 수 있다.
단점
- 토큰 자체의 데이터 크기
토큰은 암호화 된 값이며 정보를 많이 담고 있을 수도 있어, 인증 요청이 많으면 많아질 수록 네트워크 부하가 심해질 수 있다. - Payload (사용자 정보 담는 공간) 자체는 암호화 되지 않음
유저의 중요한 정보는 담을 수 없다. - 탈취의 위험성
토큰은 stateless방식을 사용함으로 한번 발행된 토큰은 탈취당하면 서버에서 대처하기 어렵다.
JWT를 토큰으로 많아 사용한다.
https://naturecancoding.tistory.com/109
[Security/JWT] JWT 기초
JWT 정의JSON Web Token 정보를 안전하게 전송하기 위한 표준 방법 중 하나.Json객체를 사용해서 정보를 저장하고, 디지털 서명을 통해서 검증한다.JWT 구성 요소1. HeaderJWT의 타입과 해싱 알고리즘 정보
naturecancoding.tistory.com
장단점 비교
저장 위치 | 클라이언트(브라우저) | 서버 | 클라이언트(주로 로컬 스토리지 또는 세션 스토리지) |
보안성 | 클라이언트에 저장되어 XSS 공격에 취약할 수 있음. Secure, HttpOnly 속성을 통해 보안 강화 가능 | 서버에 저장되어 상대적으로 안전함 | 클라이언트에 저장되어 있으나 암호화 및 서명으로 무결성 보장 |
상태 유지 | 상태 정보가 쿠키에 저장되므로 클라이언트 측에서 관리. 상태 유지를 위해 서버와의 동기화가 필요 없음 | 서버에서 상태 정보를 유지. 세션 ID를 통해 클라이언트를 식별 | 상태 정보가 토큰에 포함되므로 클라이언트 측에서 관리. 서버에 상태 정보를 저장하지 않음 |
확장성 | 서버에 부하가 적음 | 서버 메모리에 세션 데이터를 저장하므로, 동시 사용자 수가 많아질수록 서버 부하 증가 | 무상태(stateless) 방식으로 서버 부하가 적고, 확장성이 뛰어남 |
사용 편의성 | 브라우저가 자동으로 쿠키를 관리하고 전송 | 서버 측에서 세션을 관리하므로 개발자가 상태 관리를 신경 쓰지 않아도 됨 | 클라이언트 측에서 토큰을 관리해야 하므로 추가적인 코드가 필요 |
취약점 | CSRF, XSS 등의 공격에 취약. 쿠키 탈취 시 보안 문제 발생 가능 | 세션 ID 탈취 시 보안 문제 발생 가능. 세션 저장소의 부하 증가 | 토큰 탈취 시 보안 문제 발생 가능. 유효 기간이 긴 토큰의 경우 위험성 증가 |
유효 기간 | 쿠키의 만료 시간 설정 가능 | 세션은 서버 설정에 따라 만료. 일반적으로 브라우저 종료 시 만료 | 토큰의 만료 시간을 설정 가능. 유효 기간이 끝나면 새로운 토큰 발급 필요 |
복잡성 | 설정 및 사용이 간단 | 비교적 간단 | 초기 설정이 다소 복잡할 수 있으나, 설정 후에는 사용이 용이 |
사례 | 사용자의 로그인 상태 유지, 웹 사이트의 사용자 설정 저장 | 쇼핑몰 장바구니, 사용자 로그인 세션 관리 | 분산 시스템에서 사용자 인증, API 인증, 마이크로서비스 아키텍처에서 서비스 간 인증 |
Coding, Software, Computer Science 내가 공부한 것들 잘 이해했는지, 설명할 수 있는지 적는 공간