1、Session原理
服务器为了表示是哪个用户,在用户第一次登陆成功后将用户信息保存在session中,并且命令浏览器保存一个jsessionid = value的cookie,并且该浏览器每次访问想访问的服务的功能的时候都带着cookie,但是浏览器关闭后就会清楚cookie,下次访问的时候没有jsessionid就会再去重复步骤。
2、 分布式Session要解决的问题
在分布式情况下一般会使用一般的Session会造成两个问题:
-
同一服务下,Session要复制多份,这样才能保证每个服务有相同的Session
-
不同服务下,Session是有作用域的。
解决方法:
-
session复制
-
cookie本地化
-
hash一致性:根据ip进行hash取余,将ip负载均衡到不同的服务器
-
统一存储,将所有Session都统一放在redis中,进行统一管理,缺点:增加了网络成本 优点:保证了数据安全
3、 整合SpringSession解决分布式Session问题
引入依赖
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
加入配置
session:
store-type: redis
timeout: 30m
主启动类
@EnableRedisHttpSession
@Configuration
public class GulimallSessionConfig {
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
//放大作用域
cookieSerializer.setDomainName("gulimall.com");
cookieSerializer.setCookieName("GULISESSION");
return cookieSerializer;
}
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return new GenericJackson2JsonRedisSerializer();
}
}
4、核心原理
- 建立一个认证服务器,当其他服务需要登陆操作的时候就带着登陆后需要重定向的地址转发到认证服务器上进行登陆,登陆成功后设置一个uuid或者由ip、用户id等等随机生成的token,将token保存到cookie中,并将这个token和对应的用户信息以key-value的形式保存到redis中,并带着token重定向到指定url。
- 需要登陆的服务器拿到认证中心返回来的token,将这个token也保存到cookie中,并向redis查询出对应的用户信息保存到自己的session或cookie中完成登陆。
- 因为浏览器每次发送请求都会带着cookie去发送,因此在用户登陆成功后每次请求都带着token,所以可以通过服务器端建立一个filter来判断是哪个用户发送的请求。
- 当其他未登录的模块需要登陆的时候,也转发请求带着回调地址发送给认证中心,如果认证中心cookie中有其他已登录模块存留的cookie那么认证中心就将这个token返回给该模块,该模块拿到后再根据token找redis拿用户数据,将token和数据存到自己的cookie或者session中,完成登陆。
- 这样就实现了多个微服务之间的单点登陆的操作。