如何解决Session在有SpringCloudGateway架构下的Session同步问题
背景
近期在给公司的项目做登录模块相关的内容,由于公司的项目是在老框架上,所以需要做一个迁移,迁移的时候将原有的网关改成了SpringCloudGateway,作用暂时只是对用户的请求做一个路由转发以及做统一的后端跨域处理。在做登录模块的时候,参考了公司的其他项目,主要是用户登录后将用户信息存储到Session中,从而让之后的每个请求能从session里面拿到登录时候存储的用户信息。但是后面发现,其他请求一直无法从session中拿到用户信息,通过排查后发现是由于SpringCloudGateway转发的每次请求,session是不能透传的,只要经过网关,每次请求都是新的session,也导致了其他请求没法从session中拿出已经登录的用户的信息。后面由于其他问题,我们必须必须得解决session问题在同一用户请求的情况下,但是session每次都不一样的问题,所以准备使用SpringSession这个组件来解决。
集成SpringSession遇到的问题
由于SpringSession是通过Cookie来做分布式下session的处理,所以就需要对浏览器的Cookie的做一定的处理。主要问题发生在Cookie有一个SameSite的属性上,该属性有三个值Strict、Lax、None。在集成SpringSession时,发现由于这个Cookie的SameSite属性,导致从浏览器返回sessionId给Cookie时,响应的Set-Cookie这个属性一直是处于失败状态。具体原因是因为,在集成SpringSession时,将Cookie的SameSite属性设置为了None,在这个情况下,Cookie的Secure属性必须为true。在这个情况下,由于我们的项目是处于搬迁后的初期测试状态,还暂时不支持https的方式,所以导致集成SpringSession一直不成功,Set-Cookie一直会有一个黄色感叹号。
集成过程中发生的奇葩现象
在本地进行集成时,发生了一个奇葩现象。
奇葩现象:网关打印的Session一致,但是在后端微服务(除了登录微服务外)的Session却不一致
将SameSite属性设置为none后,在不知情的情况下,我也继续做了测试,所以我在本地起了Redis后,在启动类、配置文件、pom文件做了相关的设置之后,我在网关的过滤器里统一做了对请求中的sessionId做统一的打印,发现在网关这一层,所有的sessionId在做了相应的集成都是一致的,但是却在后端的微服务打印的sessionId和网关这一层打印的SessionId不一致。在网关这一层一点处理,就是从请求中获取中获取WebSession对象,然后根据WebSession对象得到的sessionId去使用getAttribute的方式获取存在Session里面的数据,每次请求都获取到了Session里面的数据,当然,由于后端的sessionId不一致,所以也导致在后端服务的接口中,没办法从session中取出来这个对象。所以,要在接口里面要对登录用户信息做处理的逻辑没有完成。还有奇怪的现象是,登录微服务是我自己单独起的,登录微服务的sessionId是和网关一致的,但是后端的其他微服务却和网关的sessionI不一致。我考虑的原因可能是因为其他的后端微服务是迁移的,很多东西都是直接搬迁,所以其他的后端微服务其实是有会存在一个问题,我在本地测试的时候,用的是我本地的Redis(后端微服务也是用的我自己本地的Redis),除了登录微服务,其他的后端微服务除了有我本地的Redis配置外,还有一个我们内网的Redis集群,所以这里面可能会有一些问题,目前没办法验证这个问题。