[CS Study] 3주차(1) - HTTP의 상태 유지 기술

bagt13·2025년 4월 15일
0

CS

목록 보기
17/27

🌐 HTTP의 상태 유지 기술

앞선 2주차에, http의 특징들을 공부하며 http가 가지는 특징인 무상태성(stateless)에 대해 알아봤다. stateless라는 특징이 가지는 장점(효율성 및 확장성)도 있지만, 단점(서버가 이전 요청을 기억하지 못한다)도 존재했다.

이러한 단점을 해결할 수 있는 기술들에는 쿠키, 세션, jwt(토큰) 등이 있다.


쿠키는 클라이언트(브라우저)에서 상태를 저장하고, 이 정보를 요청때마다 자동으로 서버에 전달하는 방식이다.

작동 방식

  1. 특정 요청에 대해 서버가 상태를 알아야 하거나, 클라이언트의 요청을 식별해야 하는 경우 쿠키를 생성하여 클라이언트로 전달한다.

  2. 쿠키를 받으면 브라우저는 이후 같은 도메인으로 요청을 보낼 때마다 쿠키를 자동으로 포함시켜서 보낸다.

    -> 서버는 클라이언트가 보낸 쿠키를 통해 사용자의 상태를 알 수 있다.


🟢 장점

1. 서버 부하가 적다

  • 서버는 쿠키를 별도로 관리할 필요 없이 클라이언트가 쿠키를 저장하고 전송한다.

2. 도메인별 제한

쿠키는 설정된 도메인에서만 사용이 가능하다 -> 보안 강화

  • 특정 도메인으로 발급된 쿠키는 해당 도메인의 하위 도메인에서만 접근 가능하다.
  • 서버에서 쿠키를 발급 할 때에는, 자기 자신 또는 상위 도메인만을 Cookie의 Domain으로 지정할 수 있다.

참고

이 부분에 대해 프로젝트를 진행하면서 공부했던 내용이 있다.

브라우저에 쿠키(Cookie)가 전달되지 않는 문제 해결


🔴 단점

1. 보안 문제

  • 정보를 쿠키에 저장하면 XSS(Cross-Site Scripting) 공격에 노출될 수 있다.

2. 크기 제한

  • 쿠키의 크기에는 제한이 있기 때문에 많은 데이터를 저장하기 어렵다.

💾 세션 (Session)

세션은 서버에서 상태를 저장하고, 클라이언트는 session id만 전달하여 서버가 상태를 찾을 수 있게 하는 방식이다.

작동 방식

  1. 클라이언트가 서버에 요청을 보내면, 서버는 session id를 생성해서 클라이언트에게 보낸다 (일반적으로 쿠키에 저장된다).

  2. 클라이언트는 이후 요청마다 session id를 포함하여 서버에 보내고, 서버는 이를 통해 세션을 조회한다.

🟢 장점

1. 높은 보안성

session id만 쿠키에 담아서 전송되기 때문에 다른 방식에 비해 더 안전하다.

2. 유연하게 데이터를 저장할 수 있다

서버에서 상태 관리상태 정보를 서버에서 관리하므로 데이터 저장에 더 유연하다.

🔴 단점

1. 서버 부하가 크다

서버에 상태를 저장하는 만큼 서버 자원 소모가 크다.

2. 서버 확장성이 좋지 않다

서버가 여러 대일 경우, 세션 동기화 처리가 등 별도의 처리가 필요하다.


3. 🧿 토큰 (jwt)

토큰 방식은 클라이언트가 토큰을 보유하고 있으며, 서버는 이 토큰을 통해 사용자의 상태를 인증하고 유효성 검사를 하는 방식이다.

작동 방식

  1. 클라이언트의 요청에 대해 서버는 토큰을 발급하여 클라이언트에 전달한다.

  2. 클라이언트는 이후 요청 시 header 또는 쿠키에 토큰을 포함시켜 요청을 보낸다.

  3. 서버는 이 토큰의 정합성을 검증하고, 토큰에 포함된 정보를 기반으로 사용자 상태 등을 확인한다.

🟢 장점

1. 뛰어난 확장성

서버는 토큰을 저장하지 않고 클라이언트에서 상태를 관리하기 때문에 확장성이 좋다.

2. 클라우드나 분산 환경에 적합하다

분산 환경에서 상태를 서버 간 공유할 필요 없이 클라이언트 측에서 관리할 수 있다.

🔴 단점

비교적 큰 크기

JWT와 같은 토큰은 종종 크기가 클 수 있으며, 매번 요청 시 토큰을 포함시켜야 하기 때문에 성능에 영향을 줄 수 있음.



🔐 토큰의 서명(Signature)과 암호화(Encryption)에 대해

토큰(jwt)의 특징에는 서명(Signature)과 암호화(Encryption)가 있는데, 비슷해보이지만 다르다.

1. 서명(Signature)

서명은 데이터의 무결성(integrity)을 보장하기 위해 사용된다.

서명된 JWT는 서버만 알고 있는 비밀 키(secret key)를 사용하여 생성되며, 이 서명으로 서버에서는 데이터가 변경되지 않았음을 검증할 수 있다.

하지만 서명은 데이터를 암호화하지 않아서, 서명된 JWT의 내용을 누구든지 볼 수 있다.

즉, 서명은 데이터의 진위 여부를 확인하는 역할을 하며, 내용을 암호화하지는 않는다.

2. 암호화(Encryption)

암호화는 데이터를 숨기는 역할을 한다.

JWT에 암호화를 적용하려면, 별도의 JWE (JSON Web Encryption) 표준을 사용해야 하며, JWE는 JWT의 내용을 암호화하는 방법이다. JWE를 사용하면 토큰의 header, paylead 뿐만 아니라 signature도 암호화할 수 있다.

따라서, JWE를 사용하지 않은 토큰은 Base64 디코딩만으로 확인 가능하다.



⚙️ 토큰의 보안성에 대해

토큰의 서명과 암호화에 대해 공부하고 난 후, '대부분의 웹 서비스에서는 당연히 JWE를 사용하겠구나' 라고 생각했지만, 찾아보니 다음과 같은 이유로 인해 대부분 JWE를 사용하지 않는다고 한다.

일반적인 웹 서비스에서는 대부분 JWE 같은 암호화 기술을 사용하지 않고, JWS 서명, HTTPS, 다양한 전략들을 통해 충분한 보안을 확보한다.

1. HTTPS 사용

대부분의 웹 서비스는 HTTPS를 사용하고, 요청 자체가 HTTPS로 암호화되어 전송되기 때문에 네트워크 구간에서 토큰이 탈취될 가능성은 매우 낮다.

2. JWE의 복잡성과 비용

암호화된 토큰은 크기도 커지고, 복호화 처리도 추가로 필요해서 성능에 영향을 줄 수 있다. 서버 간 통신에서도 JWS로 충분한 경우가 많고, JWE까지 쓰는 건 성능과 개발 복잡도 측면에서 부담되는 경우가 많다.

3. 민감한 정보는 JWT에 담지 않는다

실제 서비스에서는 토큰의 payload에 비밀번호, 주민번호 같은 민감한 정보는 절대 넣지 않는다. 대부분의 경우 role, username 정도를 넣기 때문에, 탈취되더라도 큰 피해가 생기지 않도록 설계한다.

4. 추가적인 보안 장치 (RTK, TTL, blacklist 전략 등)

  • ATK의 TTL을 짧게 설정함으로써 피해를 최소화하는 방식을 사용한다.

  • RTK를 HttpOnly+Secure를 적용한 쿠키로 저장한다.

    • JS에서 접근 불가, HTTPS에서만 전송 -> 탈취 어려움
  • 로그아웃 처리 시 서버에서 Redis 등에 RTK blacklist를 추가하여 해당 토큰을 이용한 요청을 막는다.

profile
백엔드 개발자입니다😄

0개의 댓글