黑马点评-短信登录
基于Redis实现短信登录
0.前言:
短信验证登录过程中需要共享session:
- 1.发送短信验证码:保存验证码到session
- 2.短信验证码登录注册:根据手机号查询用户,如果是新用户要先进行注册,再保存用户到session
- 3.验证登录状态:cookie中有sessionID,判断用户是否存在,进行拦截或者保存到ThreadLocal,再放行
问题:
- 每个tomcat中都有一份属于自己的session,多台Tomcat不共享session存储空间,切换时数据丢失
替代要求:
- 数据共享
- 内存存储,数据处理速度快
- key,value结构
故选择Redis进行解决
1.采用Redis的业务流程:
细节:
1.key和数据结构的选择:
- 保存验证码:用手机号作为key
- 手机号是唯一的,并且恰好与验证码绑定
- 采用String类型存储code
- 保存用户对象:用随机生成的token作为key
- token需要传递给前端,并在每次请求中被携带,用手机号会有泄露风险
- 采用Hash结构存储用户对象,相比String采取Json格式,Hash结构每个字段相互独立,可以单独CRUD,并且内存占用更少
2.选择合适的有效期:
- token要设置一定的有效期,用户长期不操作,就失去登录状态
3.选择合适的存储粒度DTO
- 用户对象本身的信息是很丰富的,还包括手机号,密码等隐私信息,在登陆阶段不需要保存和传递这么多信息,可以新建一个UserDTO类来代替
2.技术要点:
ThreadLocal:
- 在threadLocal中,他的put方法和他的get方法, 都是先从获得当前用户的线程,然后从线程中取出线程的成员变量map,只要线程不一样,map就不一样,所以可以通过这种方式来做到线程隔离
- 所以可以实现每个用户的保存和相关信息的读取
User转Hash存储:
- userDTO转Map再存储到Redis过程中,由于使用的是StringRedisTemplate要求所有的字段都是String类型,但是id是Long类型的,所以需要再进行一步手动转化
1 | |
刷新token有效期优化:
在只有一个拦截器的情况下,拦截器里的过程:
- 获取token信息
- 查询Redis的用户,不存在就拦截,存在就继续
- 保存到ThreadLocal中
- 刷新token有效期
- 放行
那么如果用户进行了不需要登录验证的操作,比如查看首页,那么拦截器不会拦截,token就得不到刷新,是有问题的。
解决:增加一个拦截一切路径的拦截器
第一个拦截器:(所有路径)
- 获取token信息
- 查询Redis的用户
- 保存到ThreadLocal中
- 刷新token有效期
- 放行
第二个拦截器:(需要登陆的路径)
- 不存在就拦截,存在就继续
完美实现token的及时刷新
黑马点评-短信登录
http://example.com/2024/02/01/网上技术学习/短信登录/