关于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>
搞定
相关文章推荐
- 利用redis写webshell
- Spring boot配合Spring session(redis)遇到的错误
- redis数据类型-散列类型
- Redis学习资料汇总
- Codis 是一个分布式 Redis 解决方案
- redis——持久化篇
- redis replica时触发了BGSAVE FAIL的问题
- Redis 启动与授权
- tomcat+redis实现session共享
- php redis 的一些操作常例!
- redis 队列 生产者 消费者模式
- PHP使用Redis二
- 超强、超详细Redis数据库入门教程
- redis 下载启动,设置、查询超时时间
- RedisHelper帮助类
- 用Redis构建分布式锁
- redis使用规范
- redis上tomcat和session共享的问题
- window 下PHP redis扩展插件
- 基于redis的sentinel的主从复制和主从切换(二)