tomcat多域名共享cookie,共享session以及修改sessionCookieName的解决方案

最近把工程拆分为多个模块分别部署,使用了多个二级域名,面临多个二级域名之间 session 不能共享的问题,带来的麻烦就是用户在主域名登陆,但由于多个域名 session 不能共享 ,因此无法进行登陆的操作,对一些功能有一些影响。


问题的原因如下:

Tomcat 下,不同的二级域名,Session 默认是不共享的,因为 Cookie 名称为 JSESSIONID 的 Cookie 根域是默认是没设置的,访问不同的二级域名,其 Cookie 就重新生成,而 session 就是根据这个 Cookie 来生成的,所以在不同的二级域名下生成的 Session 也不一样。

找到了其原因,就可根据这个原因对 Tomcat 在生成 Session 时进行相应的修改。


快速解决方案1:
在项目的/MET-INF/ 目录下创建一个 context.xml 文件,内容为:
1 2

Done!


快速解决方案2:

修改 Tomcat 的 server.xml 文件,内容为:

1
Done!

以上两种方案的详细讲解见:http://tomcat.apache.org/tomcat-6.0-doc/config/context.html


快速解决方案3:

生成一个叫做 crossSubdomainSessionValve.jar 的文件,用的时候放在 Tomcat lib 目录下,然后修改 Tomcat server.xml 文件:

1
原理:取代由 Tomcat 域产生的会话 cookie ,允许该会话 cookie 跨子域共享。
代码:
package me.seanchang; import  java .io.IOException; import  java .util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import org.apache.catalina.Globals; import org.apache.catalina.connector.Request; import org.apache.catalina.connector.Response; import org.apache.catalina.valves.ValveBase; import org.apache.tomcat.util.buf.MessageBytes; import org.apache.tomcat.util.http.MimeHeaders; import org.apache.tomcat.util.http.ServerCookie; public class CrossS ubdomainSessionValve extends ValveBase { private static Logger log = Logger.getLogger('CrossSubdomainSessionValve'); public CrossSubdomainSessionValve() { super(); info = 'me.seanchang.CrossSubdomainSessionValve/1.0'; } @Override public void invoke( Request  request, Response response) throws  IOException , ServletException { // this will cause Request.doGetSession to create the session cookie if // necessary request.getSession(true); // replace any Tomcat-generated session cookies with our own Cookie[] cookies = response.getCookies(); if (cookies != null) { for (int i = 0; i < cookies.length; i++) { Cookie cookie = cookies[i]; log.info('CrossSubdomainSessionValve: Cookie name is ' + cookie.getName()); if (Globals.SESSION_COOKIE_NAME.equals(cookie.getName())) replaceCookie(request, response, cookie); } } // process the next valve getNext().invoke(request, response); } protected void replaceCookie( Request  request, Response response, Cookie cookie) { // copy the existing session cookie, but use a different domain Cookie newCookie = new Cookie(cookie.getName(), cookie.getValue()); if (cookie.getPath() != null) newCookie.setPath(cookie.getPath()); newCookie.setDomain(getCookieDomain(request)); newCookie.setMaxAge(cookie.getMaxAge()); newCookie.setVersion(cookie.getVersion()); if (cookie.getComment() != null) newCookie.setComment(cookie.getComment()); newCookie.setSecure(cookie.getSecure()); // if the response has already been committed, our replacement strategy // will have no effect MimeHeaders headers = new MimeHeaders(); if (response.isCommitted()) log.info('CrossSubdomainSessionValve: response was already committed!'); // find the Set-Cookie header for the existing cookie and replace its // value with new cookie headers = response.getCoyote Response().getMimeHeaders(); for (int i = 0, size = headers.size(); i < size; i++) { if (headers.getName(i).equals('Set-Cookie')) { MessageBytes value = headers.getValue(i); if (value.indexOf(cookie.getName()) >= 0) {  StringBuffer buffer = new  StringBuffer (); ServerCookie .appendCookieValue(buffer, newCookie.getVersion(), newCookie.getName(), newCookie.getValue(), newCookie.getPath(), newCookie.getDomain(), newCookie.getComment(), newCookie.getMaxAge(), newCookie.getSecure(), true); log.info('CrossSubdomainSessionValve: old Set-Cookie value: ' + value.toString()); log.info('CrossSubdomainSessionValve: new Set-Cookie value: ' + buffer); value.setString(buffer.toString()); } } } } protected  String getCookieDomain( Request  request) {  String  cookieDomain = request.getServerName();  String [] parts = cookieDomain.split('\\.'); if (parts.length >= 2) cookieDomain = parts[parts.length - 2] + '.' + parts[parts.length - 1]; return '.' + cookieDomain; } public  String toString() turn ('CrossSubdomainSessionValve[container=' + container.getName() + ']'); } }
将以上代码导出一个jar文件,放入 $CATALINA_HOME/lib 中,修改 $CATALINA_HOME/conf/server.xml 文件,加入:
1

重启 Tomcat ,Done !


附:修改sessionCookieName的方法:

tomcat6和tomcat7修改方法相同

在Context容器标签上增加sessionCookieName参数

sessionCookieName=”yoursessionname”>




你可能感兴趣的:(架构设计)