深入理解登录机制---初识
一、从单体应用到分布式系统到微服务(登录解决方案)
1、单体应用
单体应用,用户登录认证完(前端的账号密码加密和库里的加密做对比),将用户信息存session里面,然后TOMCAT向客户端发送一个JSESSIONID 来记录此次会话,此后每次请求都会将JSESSIONID 发送给后台,然后拿到此次会话的session,然后取出用户信息,以此来保持登录状态。
缺点:
1. 单一服务器,部署多台Session不共享
解决方案:通过nginx 的ip_hash策略
每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题(这样由于客户第一次访问服务端到A服务后,这个客户以后的请求,nginx都会给他转发到A服务器,就不用考虑session共享的问题)。 例如:
如果 用户 一开始 就访问ip 192.168.5.21 端口80 的服务器 以后请求 都只访问 ip 192.168.5.21 端口80
2、分布式架构
分布式架构,前后分离,登录信息通过session存前置的服务器,重写了SessionManager(session管理器),用户认证后,服务器生成一个sessionid来记录此次会话状态送到前端,此后前端的每个请求都要带上此次sessionid送到请求体里面,后端通过SessionManager来拿到此次会话,然后通过固定用户key取到用户信息。
缺点:前置部署多台,Session不共享,由于是前后分离,在后台服务先投产的情况下,当用户一登录后,此时前置服务重启,Session被清掉,由于没有session了,就在服务端取不到用户信息,所以用户状态就为未登录。就算用nginx的ip_hash策略也无法解决此问题。
解决方案:利用redis实现分布式Session
将用户信息存在redis里面,服务端颁发的session_id作为key,用户信息作为value,存入redis,就算后台服务端重启后,前端发送sessionid,后台再从redis 通过key(sessionid)去取出用户信息,来维持登录状态。
由于redis一般要做集群,先有机房A和机房B 2个哨兵集群,2个哨兵之间得redis数据不共享怎么办
跨机房session共享解决方案:
暂时略过
3、微服务
微服务架构,单独的统一认证服务,校验完用户信息后,颁发令牌token 送给前端,前端每次请求带上token ,然后在网关处进行认证,取出用户信息,再进行base64加密,将加密后的用户信息塞入request里面,转发到相应的服务,然后每个服务利用SpringBoot的HandlerInterceptor进行解密,反序列化成对象后在存入request 这样写业务代码时直接从request里面去取用户对象就行了。