在传统的项目中,用户登录成功,将用户信息保存在session中,这种方式在微服务架构中会产生一系列问题。例如在购物车服务具有多台服务器,当一个请求落在购物车1号服务器后,其session保存了用户信息,另一个请求落在了购物车2号服务器,发现没有用户信息,则重新需要进行登录。服务器之间有session不共享的问题。为了解决这一问题,tomcat提出了内存拷贝,即只需要配置一些信息即可实现多台服务器之间的session拷贝,但是这种解决方案也有缺陷,例如:
浪费空间拷贝有延时,如果在延时内有请求访问,则还会出现上述问题为了解决此类问题,我们需要使用多个服务共享的信息平台,例如Redis
2. 流程图及代码实现直接上流程图
流程图简洁明了,其中需要注意的是
Redis中存入验证码的key是手机号拼接的字符串,为什么保存用户到Redis的key要使用随机token,而不是手机号拼接的字符串呢?
因为在用户登录注册时,服务器会获取到手机号,所以可以使用手机号作为key,进行验证手机号和验证码时也方便进行匹对,那么在保存用户信息到Redis时为什么要使用随机token呢?因为在用户独立成功后,用户的每次请求都会携带cookie,如果将保存用户信息的key设置为含手机号的,那么用户的请求中的cookie也需要携带手机号,这样就会有一定的安全风险,所以在用户登录成功后,我们随机生成token,用token作为key,并且返回给前端token,这样前端请求时就会携带token,也避免了安全隐患。
2.1 生成验证码保存到Redis 2.2 登录验证 2.3 请求拦截器有些请求是需要用户登录才能进行访问的,所以我们设置一个登录拦截器先拦截请求,判断用户是否登录,如果登录了就进行放行即可。
2.3.1 实现HandlerInterceptor类
preHandle方法是在controller之前运行,在这个方法里面可以进行验证登录状态的操作。
为什么要将用户保存到ThreadLocal?因为每一个线程都是独立的,如果将用户信息保存到公共变量中,会造成线程安全问题,每一个线程都具备一个ThreadLocal内存,我们将用户信息保存到ThreadLocal中即可实现线程独享一份用户信息为什么要刷新Redis中用户信息的有效时长?因为在session中,其机制是当用户不在使用session中的数据超过30分钟就会剔除session的数据,所以在拦截器的前置拦截中进行刷新即可上述代码的第三步骤,为什么userMap为空了还要放行呢?因为这个拦截器只是做Redis用户信息刷新存活时间的功能,真正拦截的是LoginInterceptor,LoginInterceptor代码在下面展示两个拦截器配置了,但是没有生效,需要在配置类里进行配置
这里配置两个拦截器,两个拦截器是有先后顺序的,上述已经说明,通过设置order属性即可配置先后顺序,值越小,优先级越高。
3. 总结用户获取验证码存放到redis
登录请求拿着验证码和手机号去进行匹配,匹配成功后将用户信息存入redis
需要登录的请求会访问拦截器,两个拦截器,第一个拦截器RefreshTokenInterceptor负责刷新redis中用户信息的TTL,并且如果Redis中有用户信息,将存入ThreadLocal,第二个拦截器LoginInterceptor 用于检测ThreadLocal是否具有用户信息,如果没有,则前往登录界面,如果有就放行
到此这篇关于Redis实现登录注册的示例代码的文章就介绍到这了,更多相关Redis 登录注册内容请搜索七叶笔记以前的文章或继续浏览下面的相关文章希望大家以后多多支持七叶笔记!