Java 웹 애플리케이션의 세션 관리

HTTP는 상태를 유지하지 않습니다(stateless). 이는 브라우저의 모든 요청이 완전히 새로운 상호작용임을 의미합니다. 서버는 사용자가 누구인지, 혹은 직전에 무엇을 했는지 기억하지 못합니다.

세션 관리가 없다면 웹사이트는 제대로 작동할 수 없습니다.

  • 페이지를 클릭할 때마다 매번 로그인을 해야 합니다.
  • 페이지를 이동할 때마다 장바구니가 비워집니다.
  • 개인 설정이 즉시 사라집니다.

세션 관리는 연속성을 만들어 줍니다. 이를 통해 서버는 여러 요청을 하나의 사용자와 연결할 수 있습니다.

작동 방식:

  1. 사용자가 로그인합니다.
  2. 서버가 세션을 생성합니다.
  3. 서버가 고유한 Session ID를 생성합니다.
  4. 서버가 이 ID를 브라우저로 보냅니다.
  5. 브라우저가 새로운 요청을 보낼 때마다 이 ID를 다시 보냅니다.

Java는 이를 처리하기 위해 HttpSession 인터페이스를 사용합니다. 사용자 ID나 역할(role)과 같은 데이터를 세션에 직접 저장할 수 있습니다.

일반적인 추적 방법:

  • Cookies: 가장 일반적인 방식입니다. 서버가 JSESSIONID 쿠키를 보내면 브라우저가 나머지를 처리합니다.
  • URL Rewriting: ID를 웹 주소에 추가합니다. 사용자가 쿠키를 비활성화한 경우에도 작동합니다.
  • Hidden Form Fields: ID가 HTML 폼 내부에 유지됩니다.

보안은 가장 큰 과제입니다. 공격자가 Session ID를 탈취하면 사용자로 위장할 수 있습니다.

안전하게 유지하기 위한 규칙:

  • JavaScript를 통한 탈취를 막기 위해 HttpOnly 쿠키를 사용하세요.
  • 데이터가 HTTPS를 통해서만 전송되도록 Secure 쿠키를 사용하세요.
  • CSRF 공격을 방지하기 위해 SameSite 설정을 사용하세요.
  • 사용자가 로그아웃할 때는 항상 session.invalidate()를 호출하세요.
  • 세션 고정(fixation) 공격을 방지하기 위해 로그인 후에는 새로운 세션을 생성하세요.

대규모 기업을 위한 확장성(Scaling): 표준 세션은 단일 서버에서 작동합니다. 하지만 대규모 애플리케이션은 로드 밸런서(load balancer) 뒤에 있는 여러 대의 서버를 사용합니다. 만약 서버 A에 사용자의 세션이 있다면, 서버 B는 사용자를 인식하지 못합니다.

이를 해결하기 위해 전문가들은 다음을 사용합니다:

  • Sticky Sessions: 로드 밸런서가 매번 사용자를 동일한 서버로 보냅니다.
  • Distributed Caching: 모든 서버가 Redis와 같은 중앙 저장소에 연결됩니다. 이것이 업계 표준입니다.

현대적인 애플리케이션은 JWT(JSON Web Tokens)도 사용합니다. 세션과 달리 JWT는 상태를 유지하지 않습니다(stateless). 데이터가 서버가 아닌 토큰 자체에 저장됩니다. 덕분에 마이크로서비스(microservices)의 확장이 더 쉬워집니다.

세션을 마스터하면 안전하고 전문적인 Java 애플리케이션을 구축할 수 있습니다.

Source: https://dev.to/naveenkumar1/session-management-in-java-web-applications-38od

Optional learning community: https://t.me/GyaanSetuAi