關於spring session redis共享session的一個坑

關於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了。既然找到了問題,解決就容易多了,下面列幾種解決方案:

  1. 改spring session源碼,並重新打包
  2. 代碼複用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> 

搞定

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章