ㅇ.ㅇ
[Tomcat] 톰캣 다중 구동환경 시 로그인 끊김 현상 / jsessionid 충돌 본문
상황
하나의 서버에 2개의 서비스 각각 설치 후 둘 다 한번에 접속하면 접속이 되지 않는 에러가 발생하였다고 문의가 들어왔다.
테스트 환경
- tomcat : 각각 다른 톰캣 사용
- port : 각각 다른 포트
- context path : 두개 모두 동일 (같은 서비스이기 때문)
- DB : 각각 다른 DB 환경
해결 과정
우선 접속은 되는 것까지 확인하였는데 하나의 서비스에서 로그인 되었을 시, 다른 쪽 서비스에서 로그인이 풀리게 되어버렸다. 개발자 도구의 쿠키 세션값을 확인해보니 동일한 값을 가지고 있는 것을 발견하였다!
구글링을 해보니 모두 jsessionid의 충돌문제이고 대부분 로그인이 풀리는 동일한 문제를 겪고 있었다. 그래서 나도 처음에는 구글에서 제일 많이 나와있는 tomcat 설정 변경을 시도해보았다.
(1) tomcat 설정 변경
tomcat의 context.xml 파일의 cookieName 지정 <Context sessionCookieName="MYSESSIONID"> 또는 web.xml파일의 cookie-config 태그의 cookie name 지정의 방식을 사용하면 독립적으로 세션이 나뉘어질 것이라고 판단하였다. 그렇지만 여전히 한쪽에서 로그인을 하면 다른 쪽에서 로그인이 풀려버렸다.
그럼 왜 tomcat을 설정을 변경해도 영향이 없을까?
(2) tomcat 설정 변경해도 영향 없는 이유
아래의 코드를 보면 spring session에서 DefaultCookieSerializer 클래스를 빈으로 등록하는 것을 볼 수 있다. 이 클래스에서 쿠키의 여러 프로퍼티들을 설정하는데 현재는 cookie name 자체를 설정하는 코드가 짜여있지 않아서 각각 톰캣 서버에서 설정한 쿠키 이름을 무시하고 srping session의 디폴트 쿠키 이름을 사용하게 되는 것이다. 따라서 톰캣 설정을 변경해도 spring session에서는 사용하는 쿠키 이름 자체가 변경되지 않아서 세션 공유에 영향이 없었다!
1 <beans:bean class="org.springframework.session.web.http.DefaultCookieSerializer">
2 <beans:property name="cookiePath" value="/"/>
3 </beans:bean>
(3) spring session에서 각각의 쿠키 이름 지정
동일한 context path를 사용하는 웹 어플리케이션들이라도 spring session은 각각의 어플리케이션에서 독립적인 세션을 관리하는데, 세션 쿠키 이름이 동일하면 브라우저 상에서는 같은 이름의 쿠키가 하나만 저장되어서 두 어플리케이션 사이에서 세션 쿠키가 공유될 수 있다. 이런 경우에는 spring session 안에서 세션 쿠키 이름을 다르게 설정하여 해결해야 한다. 그래야 각각의 어플리케이션에서 서로 다른 세션 쿠키 이름을 사용해서 세션을 저장하고, 로그인이나 로그아웃시에 각각 독립적으로 처리하기 때문이다.
1 <beans:bean class="org.springframework.session.web.http.DefaultCookieSerializer">
2 <beans:property name="cookiePath" value="/"/>
3 <beans:property name="cookieName" value="SESSION_APP1"/>
4 </beans:bean>
-
1 <beans:bean class="org.springframework.session.web.http.DefaultCookieSerializer">
2 <beans:property name="cookiePath" value="/"/>
3 <beans:property name="cookieName" value="SESSION_APP2"/>
4 </beans:bean>
위와 같이 context-security.xml파일에서 cookie 이름을 각각 지정해준다. 그러면 브라우저는 두 개의 서로 다른 세션 쿠키를 저장하고, 각각의 웹 어플리케이션에서는 서로 다른 이름의 세션 쿠키를 사용하여 세션을 저장하면서, 세션 공유 문제를 해결할 수 있다!!
테스트 결과
context path가 같기 때문에 포트가 다른 여러 개의 tomcat 인스턴스가 있어도 세션이 공유 되는 걸 확인 할 수 있었다. 그렇지만 spirng session을 사용하여 기존 쿠키 이름 대신 다른 쿠키 이름을 각각 사용했기 때문에 쿠키가 다른 인스턴스 간에 공유되지 않아 충돌이 발생하지 않는다. 즉, 새로고침 시에도 로그인이 풀리지 않게 되었다.
끝!