redis实战-短信登录

5 篇文章 0 订阅

基于session的登录流程

session的登录流程图

在这里插入图片描述

1. 发送验证码

用户在提交手机号后,会校验手机号是否合法,如果不合法,则要求用户重新输入手机号
如果手机号合法,后台此时生成对应的验证码,同时将验证码进行保存,然后再通过短信的方式将验证码发送给用户

2. 短信验证码登录、注册

用户将验证码和手机号进行输入,后台从session中拿到当前验证码,然后和用户输入的验证码进行校验,如果不一致,则无法通过校验,如果一致,则后台根据手机号查询用户,如果用户不存在,则为用户创建账号信息,保存到数据库,无论是否存在,都会将用户信息保存到session中,方便后续获得当前登录信息

3. 校验登录状态

用户在请求的时候,会从cookie中携带JsessionId到后台,后台通过JsessionId从session中拿到用户信息,如果没有session信息,则进行拦截,如果有session信息,则将用户信息保存到threadLocal中,并放行

登录拦截

为什么需要登录拦截

当执行不同的业务,访问各个controller层时,不可能在每个controller里面写检验登录状态的业务逻辑,在spring mvc中有拦截器,所有请求先经过拦截器,由拦截器决定是否需要放行,到达controller。这样校验只需要一次。在拦截器里获取到的用户信息通过threadlocal传递到controller。
在这里插入图片描述

隐藏用户敏感信息

用户信息若是直接返回,会得到许多我们不需要的信息。
所以我们应当在返回用户信息之前,将用户的敏感信息进行隐藏,采用的核心思路就是书写一个UserDto对象,这个UserDto对象就没有敏感信息了,我们在返回前,将有用户敏感信息的User对象转化成没有敏感信息的UserDto对象,那么就能够避免这个尴尬的问题了

session共享问题

每个tomcat中都有一份属于自己的session,假设用户第一次访问第一台tomcat,并且把自己的信息存放到第一台服务器的session中,但是第二次这个用户访问到了第二台tomcat,那么在第二台服务器上,肯定没有第一台服务器存放的session,所以此时 整个登录拦截功能就会出现问题,我们能如何解决这个问题呢?

早期的方案是session拷贝,就是说虽然每个tomcat上都有不同的session,但是每当任意一台服务器的session修改时,都会同步给其他的Tomcat服务器的session,这样的话,就可以实现session的共享了

但是这种方案具有两个大问题

  1. 每台服务器中都有完整的一份session数据,服务器压力过大。
  2. session拷贝数据时,可能会出现延迟

所以我们后面都是基于Redis来完成,我们把session换成Redis,Redis数据本身就是共享的,就可以避免session共享的问题了

Redis替代session的登录流程

设计key结构

首先我们来思考一下该用什么数据结构来存储数据
由于存入的数据比较简单,我们可以使用String或者Hash
如果使用String,以JSON字符串来保存数据,会额外占用部分空间
如果使用Hash,则它的value中只会存储数据本身
如果不是特别在意内存,直接使用String就好了

设计key的具体细节

我们这里就采用的是简单的K-V键值对方式
但是对于key的处理,不能像session一样用phone或code来当做key
因为Redis的key是共享的,code可能会重复,phone这种敏感字段也不适合存储到Redis中
在设计key的时候,我们需要满足两点
key要有唯一性
key要方便携带
所以我们在后台随机生成一个token,然后让前端带着这个token就能完成我们的业务逻辑了

整体访问流程

当注册完成后,用户去登录,然后校验用户提交的手机号/邮箱和验证码是否一致
如果一致,则根据手机号查询用户信息,不存在则新建,最后将用户数据保存到Redis,并生成一个token作为Redis的key
当我们校验用户是否登录时,回去携带着token进行访问,从Redis中获取token对应的value,判断是否存在这个数据
如果不存在,则拦截
如果存在,则将其用户信息(userDto)保存到threadLocal中,并放行
在这里插入图片描述
在这里插入图片描述

登录刷新问题

什么是登录状态刷新问题

我们依赖于拦截器做登录校验,需求是只要用户一直访问,token有效期就一直刷新,不会过期,但是我们拦截器拦截的路径只是需要做登录校验的路径,并不是所有路径,一个服务中存在不需要登录校验的操作(如首页等),如果用户进行不需要登录校验的请求,token的有效期不会刷新。
在这里插入图片描述

优化方案

类似责任链模式的思想,在原有拦截器的基础上,加一个拦截器,拦截一切路径,在第一个拦截器中做刷新token有效期的操作。
在这里插入图片描述
既然之前的拦截器无法对不需要拦截的路径生效,那么我们可以添加一个拦截器,在第一个拦截器中拦截所有的路径,把第二个拦截器做的事情放入到第一个拦截器中,同时刷新令牌,因为第一个拦截器有了threadLocal的数据,所以此时第二个拦截器只需要判断拦截器中的user对象是否存在即可,完成整体刷新功能。

  • 29
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值