본문 바로가기

Server/WAS

Tomcat8 - JSESSIONID 세션 충돌 문제와 해결 방법

728x90

웹 애플리케이션에서 로그인 후 다른 페이지로 이동해도 계속 로그인이 유지되는 이유는 바로 세션(Session) 덕분입니다. 세션은 서버가 사용자 정보를 기억하고, 사용자가 서버와의 연결된 동안 일관된 상태를 유지하는 데 중요한 역할을 합니다.

서버는 JSESSIONID라는 쿠키를 발급하는데, 동일한 서버에 여러 톰캣을 설치하거나 한 톰캣에 여러 애플리케이션을 배포하면 예상치 못한 세션 충돌 문제가 발생할 수 있습니다.

 

세션이란 무엇인가?

세션(Session)은 웹 서버가 클라이언트(사용자)를 인식하기 위해 일정 시간 동안 유지하는 정보를 말합니다. 예를 들어, 사용자가 웹사이트에 로그인하면, 그 사용자의 로그인 상태를 서버가 기억하고 있다가 다른 페이지로 이동해도 로그인이 유지되도록 합니다.

이 세션 정보를 유지하기 위해 서버는 사용자의 브라우저에 JSESSIONID라는 쿠키를 발급합니다. 이 쿠키는 브라우저와 서버 사이의 통신에서 매번 전달되어 서버가 "아, 이 사용자는 로그인한 사용자구나"라고 기억하게 해 줍니다.

 

문제 상황: 세션 충돌

동일한 IP에서 여러 개의 톰캣 인스턴스를 포트만 달리해서 운영하거나, 하나의 톰캣에 여러 개의 애플리케이션을 배포할 때 발생하는 문제가 있습니다. 바로 세션 충돌입니다. 이 문제는 각 애플리케이션이 동일한 JSESSIONID라는 쿠키 이름을 사용하기 때문에 발생합니다.

예시

  1. A 사이트(톰캣 1)에서 사용자가 로그인하면 서버는 JSESSIONID라는 쿠키를 사용자 브라우저에 발급합니다.
  2. 사용자가 B 사이트(톰캣 2)로 이동해 로그인을 시도합니다. B 사이트도 JSESSIONID 쿠키를 사용하므로, 브라우저는 새로운 JSESSIONID를 덮어씌웁니다.
  3. 그 결과, A 사이트의 세션은 더 이상 유효하지 않게 되고, A 사이트의 로그인 세션이 종료됩니다.

왜 이런 일이 발생할까?

  • 쿠키는 도메인과 경로를 기준으로 관리됩니다. 포트 번호는 쿠키를 구분하는 기준이 아니기 때문에, 동일한 도메인(같은 IP)에서 동작하는 A 사이트와 B 사이트는 포트가 다르더라도 같은 JSESSIONID 쿠키를 공유하게 됩니다.
  • 이로 인해 A 사이트와 B 사이트가 같은 세션 ID를 사용하게 되어, 서로 다른 로그인 정보가 충돌하게 됩니다.

 

해결 방법: JSESSIONID 이름을 다르게 설정하기

이 문제를 해결하기 위해서는 각 애플리케이션이 서로 다른 세션 쿠키 이름을 사용하도록 설정해 주면 됩니다. 톰캣에서는 이를 위해 server.xml 파일에 sessionCookieName 설정을 추가할 수 있습니다.

1. 톰캣 서버별로 세션 쿠키 이름 설정하기

여러 톰캣 인스턴스를 하나의 서버에서 운영 중이라면, 각 톰캣 인스턴스가 사용하는 세션 쿠키의 이름을 변경하면 됩니다.

톰캣의 server.xml 파일에서 다음과 같이 설정을 추가합니다

<Context path="" sessionCookieName="AJSESSIONID" crossContext="true" />

여기서 중요한 것은 sessionCookieName 부분입니다. A 사이트는 AJSESSIONID, B 사이트는 BJSESSIONID로 지정하여 서로 다른 이름을 사용하게 할 수 있습니다.

2. 한 톰캣에 여러 프로젝트를 배포할 때의 해결 방법

만약 하나의 톰캣에 여러 개의 프로젝트(A, B, C 등)를 배포하고 있다면, 각 프로젝트에 대해 Context 경로(path)와 세션 쿠키 이름을 설정해 세션 충돌을 방지할 수 있습니다.

<Context path="/A" sessionCookieName="AJSESSIONID" crossContext="true" />
<Context path="/B" sessionCookieName="BJSESSIONID" crossContext="true" />
  • path: 각 애플리케이션의 경로를 지정합니다. A 프로젝트는 /A, B 프로젝트는 /B 경로로 설정됩니다.
  • sessionCookieName: 각 프로젝트마다 고유한 세션 쿠키 이름을 지정합니다.
  • crossContext="true" : 서로 다른 컨텍스트(애플리케이션 간)에서 객체를 공유할 수 있게 해 줍니다.
    세션 충돌과 관련은 없지만, 여러 애플리케이션 간에 데이터를 주고받아야 하는 상황에서는 유용합니다.

 

728x90
반응형