一.使用场景
前后端不分离的情况下,往登陆页auth.gulimall.com的session中存放一个用户信息,想要在首页gulimall.com中取出该数据并展示出来
@GetMapping("/oauth2.0/gitee/success")
public String oauth2(@RequestParam("code") String code, HttpSession httpSession) throws Exception {
......
if (r.getCode() == 0){
MemberOAuthVo memberOAuthVo = r.getData(new TypeReference<MemberOAuthVo>() {});
log.info("用户信息:{}",memberOAuthVo);
httpSession.setAttribute("loginUser",memberOAuthVo);
return "redirect:http://gulimall.com";
}
......
}
首页
二.session不共享的原因
1. 如果想要取出session数据需要通过Cookie的JSESSIONID和Domain,这里的Domain规定了session可以在那些域名下面使用,每一个域名下的的Domain是不同的,这就导致域名a的数据不能被域名b拿到
2. 并且session是存放在服务器内存中,如果是一个服务多实例的情况,那么每个服务器的内存也是无法共享session的
三.解决方法
1. 解决不同域名无法共享session的问题
放大JSESSIONID的DOMAIN作用域,实战中不可能手动修改DOMAIN范围,使用springsession解决 auth.gulimall.com -> .gulimall.com
2. 解决分布式服务(同服务不同实例)不共享session的问题
将session存在redis中
四.导入Spring Session
1.导入依赖(存的服务和取的服务都需要配置一份 )
<!--解决session不共享-->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
2.application.properties
#session存储类型
spring.session.store-type=redis
#session过期时间: 默认30分钟
server.servlet.session.timeout=30
3.启动类添加注解
自动将HttpSession中的数据存入redis,原来HttpSession源码是从currentMap内存中存取session,现在是从包装后的wrappedRequest取session,也是从redis上操作存和取session
@EnableRedisHttpSession
@EnableRedisHttpSession导入RedisHttpSessionConfiguration配置,给容器中添加了一个组件
RedisOperationsSessionRepository:Redis操作session,session的增删改查封装类
4.自定义配置类
解决Domain子域名无法获取session数据的问题
@Configuration
public class GulimallSessionConfig {
/**
* 自定义session的使用范围——Domain
*/
@Bean
public CookieSerializer cookieSerializer(){
DefaultCookieSerializer defaultCookieSerializer = new DefaultCookieSerializer();
defaultCookieSerializer.setDomainName("gulimall.com");
defaultCookieSerializer.setCookieName("GULISESSION");
return defaultCookieSerializer;
}
/**
* 自定义redis序列化方式为json,原来是Serializable
*/
@Bean
public RedisSerializer<Object> redisSerializer(){
return new GenericJackson2JsonRedisSerializer();
}
}
五. 实现效果
首页
点击登陆 —> 授权成功 —> 获取用户信息 —> 用户信息存入session
在登录页与主页不同域名的情况下,登陆页授权成功往session中存入用户信息,跳转至首页 ,首页取出session中用户名并展示