본문 바로가기
Tomcat

[Tomcat] 같은 도메인 다른 포트 HTTP 세션 충돌

by jn4624 2021. 3. 3.
반응형

1. 문제점

동일한 도메인 또는 동일한 IP를 사용하여 WAS 인스턴스가 각각 다른 서비스를 제공하고 있는 경우

서비스 포트가 다름에도 먼저 로그인한 서비스의 HTTP 세션을 잃게 되어 로그아웃되는 현상.

 

2. 해결방안

Java 서블릿 엔진에서는 HTTP 세션을 추적하기 위해 클라이언트 쿠키에 JSESSIONID라는 이름으로 HTTP 세션ID 저장을 유도한다.

이때 쿠키에 값을 저장하는 기준은 도메인명과 경로다.

쿠키에서 활용하는 도메인명은 포트번호를 제외하므로 서비스 포트가 다른 것은 쿠키에 아무런 영향이 없다.

 

위와 같은 문제가 발생하는 원인은

동일한 컨텍스트 경로를 사용한다면 WAS는 쿠키에 JSESSIONID 생성 요청시 해당 경로를 사용하게 되고

나중에 생성된 JSESSIONID로 덮어씌워지게 되면서 충돌이 발생한다.

 

따라서 아래와 같은 방안이 필요하다.

 

a. 도메인명 분리

개발/테스트 환경과 같이 Public 도메인명을 부여하기 어려운 경우 클라이언트 PC의 hosts 파일에 강제로 도메인명을 지정하는 방법이 있다.

쿠키는 도메인명이 다르면 별도로 생성되므로 충돌 위험이 사라진다.

 

b. 컨텍스트 경로 분리

각 WAS 인스턴스에 디플로이되는 어플리케이션 컨텍스트 경로를 분리하는 방법이 있다.

서비스1의 경로를 /로 설정한다면 서비스2의 경로를 다르게 설정하는 것이다.

그리하면 경로에 따라 별도 쿠키가 생성되어 충돌 위험이 사라진다.

 

‼️ 주의

이 경우 어플리케이션에 영향(URL 매핑, 리소스 링크 등)이 있을 수 있으므로 검토가 필요하다.

‼️ 참고

컨텍스트 경로를 별도로 지정하지 않았을 경우에는 .war 압축 푼 디렉토리명이 컨텍스트 경로가 된다.

예) 디렉토리명이 ROOT면 컨텍스트 경로는 /, 디텍토리명이 app이면 컨텍스트 경로는 /app

 

c. HTTP 세션ID를 다르게 저장

세션ID를 저장하는 쿠키명을 각각 다르게 설정하는 방법이 있다.

서비스1의 세션ID를 기본 이름인 JSESSIONID로 저장한다면 서비스2의 세션ID를 APP_JSESSIONID와 같이 다르게 설정하는 것이다.

 

‼️ 주의

- 세션ID를 제외한 쿠키명 충돌

세션ID 외에 어플리케이션 쿠키에 직접적으로 설정하는 값이 있을 경우

이들 모두에 대한 쿠키명이 충돌하지 않도록 설정해야 한다.

- 모든 쿠키값 전송

도메인명과 경로가 동일하면 각 서비스들은 같은 쿠키를 공유하게 된다.

세션ID를 저장하는 쿠키명을 분리하더라도 HTTP의 특성상 해당 쿠키에 존재하는 모든 값들이 서버와 통신하는 시점에 모두 전송된다.

즉 서비스2와 통신할 때도 서비스1에서 설정한 쿠키값들이 같이 전송된다.

따라서 쿠키에 저장된 값이 많을 경우 네트워크 구간에서 오버헤드가 될 수 있으므로 가급적 쿠키 사용량을 최소화할 필요가 있다.

 

3. HTTP 세션ID 지정하는 방법 3가지

a. Deployment Descriptor 지정하는 방법

웹 어플리케이션의 Deployment Descript의 web.xml파일에서 아래와 같은 형태로 설정

<session-config>
    <cookie-config>
        <name>APP_JSESSIONID</name>
    </cookie-config>
</session-config>

 

b. Servlet Listener를 작성하여 프로그램상에서 지정하는 방법

웹 어플리케이션에 별도의 Listener를 개발하여 컨텍스트 초기화 이벤트 발생시 원하는 쿠키명을 설정

web.xml 파일에 설정하는 방식과 동일한 효과

public void contextInitialized(ServletContextEvent servletContextEvent) {
    ServletContext servletContext = servletContextEvent.getServletContext();
    SessionCookieConfig sessionCookieConfig = servletContext.getSessionCookieConfig();
    sessionCookieConfig.setName("APP_JSESSIONID");
}

 

c. WAS에서 지정하는 방법

WAS 제품에서 제공하는 방식에 따라 설정 가능하며 웹 어플리케이션 내에서 지정하는 것보다 우선한다.

Servlet 3.0미만을 사용하는 경우 웹 어플리케이션 단위로 지정할 수 없으므로 반드시 이 방법으로 설정해야 한다.

server.xml파일에서 아래와 같은 형태로 설정

<Context docBase="/app/web" path="/aw" reloadable="true" sessionCookieName="APP_JSESSIONID" />

 

 

🙏 참조 ::

반응형

'Tomcat' 카테고리의 다른 글

[Tomcat] DATASOURCE(데이터베이스) 동적 속성 적용  (0) 2021.04.29
[Tomcat] catalina.out 초기화  (0) 2021.03.03
[Tomcat] catalina.out 로그 관리  (0) 2021.03.03