tomcat server 같은 도메인(IP)에서 Port번호가 다르지만 세션을 공유하는 문제 해결 방법(로그인 튕김등)


진행중인 프로젝트가


각각의 모듈역할을 하는 war파일 3개를 하나의 was(톰캣)에 넣고 돌리는데


이런 프로젝트를 2개를 한 서버(서버컴퓨터)에 넣고 돌리니


하나를 로그인 하면


다른 하나의 로그인이 해제된다거나 하는 세션관련 문제가 생겼다.



일단 문제의 원인은 통신되는 데이터의 암호화를 위해 암호화에 필요한 키값을 세션에 넣고 로그인페이지로 날려주는데


항상 접속할때마다 키를 재사용하지 않기 위해 기존키값을 제거하고 새로운 키값을 만들어 낸다


물론 다른 세션도 삭제하고



그래서 8080포트를 쓰는 프로젝트 로그인 창을 띄우고


8082 포트르 ㄹ쓰는 프로젝트 로그인 창을 띄운 다움 8080포트를 쓰는 프로젝트 로그인을 하면


암호화키값이 맞지 않아 에러가 나고



각각 따로 로그인을 한 후 먼저 로그인한 프로젝트에서 메뉴이동을 하면 권한,사용자 세션이 날아가서


메뉴이동시 로그인만료가 되어 튕겨나가게 되는 것 이다.



또 열심히 구글링을 해서 방법을 찾았는데


내가 삽질한 시간보다 훨씬 간단한 해결방법이 있었다.


서버는 세션ID를 찾을때 특정 ID로 찾는데 이게 두 포트에서 사용되는 세션ID가 동일해서 생기는 문제였다



해결방법은 톰캣 context.xml 파일의


context 부분에 sessionCookieName="first_JSESSIONID"  이것과 같이 각각 프로젝트에 서로 다른 세션쿠키명을 적용시켜 주면 해결이 된다..



1
<Context crossContext="true" sessionCookieName="PROJECT1_JSESSIONID">
cs


이렇게 설정을 해주면 된다..


crossContext는 한 was에 war 3개가 서로 세션을 공유하기 위해 사용한 옵션이고


서로 다른 was에서 세션을 간섭하지 않게 하기 위해 세션쿠키네임 이라는 옵션을 추가해 주었다.


당연히 또다른 프로젝트에선 쿠키네임을 다른 것으로 설정해 주어야 한다.



하나의 was에 여러개의 프로젝트(컨텍스트)가 존재할 경우 일반적으론


서로간 세션의 공유가 되지 않는다. 


이때 각 컨텍스트간의 세션이 공유될 수 있는 방법을 알아보자.



1. 서버의 context.xml의 변경


1
2
3
4
5
6
7
8
9
10
<!-- The contents of this file will be loaded for each web application -->
<Context>
 
    <!-- Default set of monitored resources -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
 
    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->
cs


저 위의 컨텍스트를 아래와 같이 바꿔준다.


1
2
3
4
5
6
7
8
9
10
<!-- The contents of this file will be loaded for each web application -->
<Context crossContext="true">
 
    <!-- Default set of monitored resources -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
 
    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->
cs



2. server.xml 변경


1
 <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

cs


1
 <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" emptySessionPath="true"/>
cs


emptySessionPath="true" 를 추가 한다.



3. 세션 세팅


1
request.getSession().getServletContext().setAttribute("ssUserId", userId);

cs


기존의 방법에서 가운데 getServletContext()를 추가 하여 준다.


root로 지정되어 있지 않는 컨텍스트에선 

getServletContext("/sample") 와 같이 컨텍스트명을 지정하여 준다.



4. 세션 겟


1
String ssUserId =  (String) request.getSession().getServletContext().getContext("/").getAttribute("ssUserId");
cs


가지고 올땐 위와 같이 가져오며 루트가 아닌 컨텍스트에서 set 한 경우엔 getContext("/sample") 와 같이 컨텍스트 명을 넣어 사용 하면 된다.



+ Recent posts