您的位置:首页 > 数据库 > Redis

关于spring session redis共享session的一个坑

2015-12-29 17:44 756 查看

关于spring session redis共享session的一个坑

这两天写spring session redis发现几个小问题,挨个絮叨絮叨:

传统spring - web 的配置方案

其实免密码安装完redis, spring端只要下面这两个bean配置上就可以用了

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"/>

<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="port" value="${redis_port}" />
<property name="hostName" value="${redis_url}" />
</bean>


官方示例都是零配置的写法,画风变的太大以至于在AbstractHttpSessionApplicationInitializer这里浪费了很久。其实用上面这种方式,是完全不需要再写AbstractHttpSessionApplicationInitializer的,他们干的是一件事。

关于子域的坑

由于研究了很久AbstractHttpSessionApplicationInitializer,所以顺便看了spring session的源码。结果在debug的过程中发现spring session在获取sessionid时,在CookieHttpSessionStrategy中并没有做跨子域的处理,但这帮家伙明知道这个问题。

private Cookie createSessionCookie(HttpServletRequest request,
Map<String, String> sessionIds) {
Cookie sessionCookie = new Cookie(cookieName,"");
if(isServlet3Plus) {
sessionCookie.setHttpOnly(true);
}
sessionCookie.setSecure(request.isSecure());
sessionCookie.setPath(cookiePath(request));
// TODO set domain?
...

private static String cookiePath(HttpServletRequest request) {
return request.getContextPath() + "/";
}


其实这里只要把cookiePath的返回值设置为统一的根路径就能让session id从根域获取了,这样同根下的所有web应用就可以轻松实现单点登录共享session了。既然找到了问题,解决就容易多了,下面列几种解决方案:

改spring session源码,并重新打包

代码复用CookieHttpSessionStrategy,改cookiePath,并在spring注入时指定自己写的这份Strategy

搭建spring session源码的开发环境太麻烦了,我用的方案2

private static String cookiePath(HttpServletRequest request) {
return "/";
}


并在spring redis中加入如下配置

<bean id="redisRepository" class="org.springframework.session.data.redis.RedisOperationsSessionRepository">
<constructor-arg ref="jedisConnectionFactory" />
</bean>
<bean id="cookieHttpSessionStrategy" class="xxx.CookieHttpSessionStrategy"/>
<bean class="org.springframework.session.web.http.SessionRepositoryFilter">
<constructor-arg ref="redisRepository" />
<property name="httpSessionStrategy" ref="cookieHttpSessionStrategy"/>
</bean>


搞定
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: