问题1
一个系统中不同微服务的session共享。
问题1的解决办法
1. session复制的方法:微服务的副本之间通过通信共享session。这样每一个微服务的副本都会保存所有的session。(缺点:造成大量的通信,多处额外的通信开销。)
2. 客户端存储:将session的信息保存到用户端的cookie中,每次请求后端的时候,都会带上这个cooike。后端再解析用户的信息。(缺点:存在cookie中不安全,每次请求都要携带完整cookie,浪费带宽)
3. 通过hash一致性方法,对于1个用户ip,其请求会被固定路由到一个固定的服务器中。(缺点:session依然存储在web-server中,重启服务session会丢失。其次,当服务数量扩展的时候,路由的位置会发生改变。)
4. 使用数据库统一存储session信息,后端从数据库中获取。
第四种方法的详细介绍(SpringSession)
1.. 修改jsessionid的作用域(扩大到整个服务)。
1. 导入SpringSession依赖。
2. 在登陆所在的微服务中添加store-type=redis(用redis存储session)
3. 在启动类上方添加@EnableRedisHttpSession依赖
4. 创建Session信息类。并实现序列化。(不序列化存储到redis会报无法序列化的错误)。
5. 随后再调用session.setAttribute方法保存Session信息类的时候,会自动将其保存至redis中。
问题2
不同系统的session共享:如新浪微博系统和新浪网页之间的session共享。此时无法使用SpringSession。因为不同系统之间无法共享jsessionid。
问题2解决办法-单点登录
单点登录需要一个单独的登录认证服务器,不同系统的登录都要通过这个登陆验证服务器。核心思想就是把使用统一的登陆服务。
假如说现在有A、B两个系统。其单点登录流程如下:
用户进入A系统,A系统发现用户未登录,后端命令浏览器跳转到登录服务器。并且在重定向地址中(用?)加入参数,参数内容是A的登陆服务地址,用于表示是A系统让你跳转的,登陆成功后你得重定向到A系统主页。
此时单点登录服务跳转至登录页(统一的前端页面)。用户输入账号密码并将其发送给单点登录服务。登陆成功,单点登陆服务首先会为每一个用户生成一个唯一的令牌token作为key,value为表示用户的信息存入redis中。随后重定向至之前A系统的登录后端,并且定向地址中要加入参数,参数值为令牌。重定向到A系统的登陆后端此时A会向单点登录询问令牌的合法性,若合法则登陆成功。将token写到cookie和session中,下次用户在访问的时候,通过cookie与session的比较就能知道是谁。
此时,在登陆B系统,后端发现未登录,跳转到统一登录服务,但是之前A系统已经在统一登陆服务进行了登录,此时浏览器中的统一登陆前端cookie还保存着用户的token。此时单点登录服务会重定向到B登录后端,并将token作为参数。此时B会向单点登录询问令牌的合法性,若合法则登陆成功。(与A后面的步骤类似了)。