springboot 下 spring-session-data-redis + redis + nginx 实现session共享

1: pom引入依赖

        <!-- spring boot 与 redis 应用的基本配置 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <!-- spring session 与redis 应用环境基本配置, 需要开启redis后才可以使用, 不然启动会报错 -->
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
        </dependency>

2:配置: application.yml

server:
  port: 8080
  servlet:
    context-path: /a    //项目名称
  
spring:
  redis:
    database: 0
    host: 你的redisip
    port: 6379
    password: 你的redis密码
    pool:
      max-idle: 8
      min-idle: 0
      max-active: 8
      max-wait: 1
    timeout: 5000
  session:
    store-type: redis
    
    
redis:
   hostname: 你的redisip
   port: 6379
   pawssword: 你的redis密码

 

 

3: 增加配置类

springboot 下 spring-session-data-redis + redis + nginx 实现session共享

   3.1: SessionConfig

/**  
 * Project Name:sessionShare 
 * File Name:SessionConfig.java 
 * Package Name:com.tang.config 
 * Date:2019年5月28日 下午8:53:49 
 * 
 */
package com.tang.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnection;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.session.web.http.DefaultCookieSerializer;

/** 
 * ClassName: SessionConfig
 * Function: jedis连接redis配置 
 * date: 2019年5月28日 下午8:53:49
 * 
 * @author tangjiandong
 */
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)
public class SessionConfig {
    
    @Value("${redis.hostname}")
    private String hostName;
    @Value("${redis.port}")
    private int port;
    @Value("${redis.pawssword}")
    private String pawssword;
    
    
    /*
     * JedisConnectionFactory
     * since 2.0, configure the hostname using {@link RedisStandaloneConfiguration}.
     */
    @Bean
    public RedisStandaloneConfiguration  connectionFactory()
    {
        RedisStandaloneConfiguration jedisConnectionFactory = new RedisStandaloneConfiguration();
        jedisConnectionFactory.setHostName(hostName);
        jedisConnectionFactory.setPort(port);
        jedisConnectionFactory.setPassword(pawssword);
        
        return jedisConnectionFactory;
    }

    /**
     * 自定义返回给前端的Cookie的项目根路径
     *
     * @return
     */
    @Bean
    public DefaultCookieSerializer defaultCookieSerializer() {
        DefaultCookieSerializer defaultCookieSerializer = new DefaultCookieSerializer();
        defaultCookieSerializer.setCookiePath("/");
        return defaultCookieSerializer;
    }
     
}
 

 3.2:SessionInitializer

/** 
 * Project Name:sessionShare 
 * File Name:SessionInitializer.java 
 * Package Name:com.tang.config 
 * Date:2019年5月28日 下午9:05:21 
 * 
 * 
 */
package com.tang.config;

import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;

/** 
 * ClassName: SessionInitializer
 * Function: 初始话session配置
 * date: 2019年5月28日 下午9:05:21
 * 
 * @author tangjiandong
 */

public class SessionInitializer extends AbstractHttpSessionApplicationInitializer {
    
    public SessionInitializer() {
        super(SessionConfig.class);
    }

}
 

 

4:ngninx 配置代理访问

springboot 下 spring-session-data-redis + redis + nginx 实现session共享

 

5:controller

springboot 下 spring-session-data-redis + redis + nginx 实现session共享

 

6: 访问:  

a项目创建session

springboot 下 spring-session-data-redis + redis + nginx 实现session共享

 

 

b项目查询 , 查询正常就是已经实现session共享了。 redis中也存在

springboot 下 spring-session-data-redis + redis + nginx 实现session共享

springboot 下 spring-session-data-redis + redis + nginx 实现session共享

 

注意一点:必须在 SessionConfig 类中 实现 defaultCookieSerializer,  如果 不实现此方法将无法实现session共享。

 /**
     * 自定义返回给前端的Cookie的项目根路径
     *
     * @return
     */
    @Bean
    public DefaultCookieSerializer defaultCookieSerializer() {
        DefaultCookieSerializer defaultCookieSerializer = new DefaultCookieSerializer();
        defaultCookieSerializer.setCookiePath("/");
        return defaultCookieSerializer;
    }

 因为默认的cookie 路径是 项目路径加 / ,  会有路径问题。springboot 下 spring-session-data-redis + redis + nginx 实现session共享

 

 本人就是在a项目创建了session, redis中也有了,  但是在b 项目死活查询不到。 后面看了下面路径的这篇文章才解决。

对于浏览器上的Cookie来说,Domain和Path是决定当前请求是否要携带这个Cookie的关键。如果当前请求的域名与Domain一致或是Domain的子域名,且域名后的应用名称与Path一致,那么当前请求就会携带上此Cookie的数据。如果两个选项有一个不符合,则不会带上Cookie的数据。

默认的CookieSerializer会设置Cookie的Path为当前应用路径加上”/”,也就是说如果我一台服务器上部署了多个子应用,不同应用的路径不同,则他们生成的Cookie的Path不同,那么就导致子应用间的Cookie不能共享,而子应用共享Cookie是实现SSO的关键,所以我们需要自定义一个CookieSerializer,让所有子应用的Path均相同。如果子应用不是部署在同一台服务器上,那么需要设置他们的Domain相同,使用统一的二级域名,比如baidu.com,csdn.cn等,同时设置其Path均相同,这样才是单点登录实现的关键。设置Cookie的Domain时有点要注意,只能设置为当前访问域名或者是其父级域名,若设置为子级域名则不会发生作用,若设置为其他域名,比如当前应用的域名为www.baidu.com,但你设置Domain为www.csdn.com,这种设置形式不能实现,这是浏览器对Cookie的一种限定。
 

 问题解决参考:https://blog.csdn.net/qq_27529917/article/details/79169905