当session的作用域只限于auth.gulimall.com时,在auth.gulimall.com下登录账号所返回包含用户信息的session无法共享给gulimall.com
当我们把作用域放大更改为.gulimall.com时,auth.gulimall.com下登录账号所返回包含用户信息的session就能共享给gulimall.com
至此解决session共享跨域问题的核心关键为放大session的作用域范围。
<!--springsession解决session共享问题--> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> <version>2.2.0.RELEASE</version> </dependency>
spring.session.store-type=redis
@EnableRedisHttpSession//整合redis作为session存取 @EnableDiscoveryClient @EnableFeignClients @SpringBootApplication public class GulimallAuthServerApplication { public static void main(String[] args) { SpringApplication.run(GulimallAuthServerApplication.class, args); } } @EnableRedisHttpSession//整合redis作为session存取 @EnableCaching @EnableFeignClients(basePackages = "com.atguigu.gulimall.product.feign") @EnableDiscoveryClient @MapperScan(basePackages = "com.atguigu.gulimall.product.dao") @SpringBootApplication public class GulimallProductApplication { public static void main(String[] args) { SpringApplication.run(GulimallProductApplication.class, args); } }
官方文档:
实际代码:
@Configuration public class GulimallSessionConfig { //解决session跨域问题 @Bean public CookieSerializer cookieSerializer() { DefaultCookieSerializer cookieSerializer= new DefaultCookieSerializer(); //将session作用域放大到*.gulimall.com cookieSerializer.setDomainName("gulimall.com"); cookieSerializer.setCookieName("GULISESSION"); /* serializer.setCookieName("JSESSIONID"); serializer.setCookiePath("/"); serializer.setDomainNamePattern("^.+?\\.(\\w+\\.[a-z]+)$");*/ return cookieSerializer; } //Session序列化后转为json格式 @Bean public RedisSerializer<Object> springSessionDefaultRedisSerializer() { return new GenericJackson2JsonRedisSerializer(); } }
当我在auth.gulimall.com域名下的登录服务下将用户的账户信息传入session时:
if (oauthlogin.getCode()==0){ MemberResVo data = oauthlogin.getData("data", new TypeReference<MemberResVo>() {}); //TODO:1、session只作用当前域,无法跨域访问 //TODO:2、希望能使用JSON序列化对象 session.setAttribute("loginUser",data); return "redirect:http://gulimall.com"; }
此处使用MemberResVo实体类,所以要对其进行序列化:
@ToString @Data public class MemberResVo implements Serializable { private Long id; /** * 会员等级id */ private Long levelId; /** * 用户名 */ private String username; /** * 密码 */ private String password; //private ..... //private ..... }
至此我们可以将session返回给gulimall.com取得值并进行显示:
<a href="http://auth.gulimall.com/login.html">你好,[[${session.loginUser!=null?(session.loginUser.nickname!=null?session.loginUser.nickname:session.loginUser.socialUid):‘请登录‘}]]</a>
@EnableRedisHttpSession导入RedisHttpSessionConfiguration.class
1、RedisHttpSessionConfiguration在容器中添加了RedisIndexedSessionRepository组件:redis操作session,对数据进行持久化处理
2、被RedisHttpSessionConfiguration继承的SpringHttpSessionConfiguration中添加了SessionRepositoryFilter(session过滤器)
2.1、SessionRepositoryFilter创建时自动获取到SessionRepository;
2.2、SessionRepositoryFilter的doFilterInternal方法把原生的request和response被包装成wrappedRequest和wrappedResponse,以后获取session将不再通过原生的request.session()方法而是通过wrappedRequest.getsession(),wrappedRequest.getsession()方法中重写了request.session(),wrappedRequest.getsession()的session是从SessionRepository获取得到的,做到从redis获取session
核心代码:
所以,我们可以通过自定义SessionRepository接口更改对session的增删查改方法
原文:https://www.cnblogs.com/linchenguang/p/13517076.html