黑马点评项目

点评项目——用户登录注册

这部分主要实现发送验证码,用户登录注册。
技术点:使用token+redis的方式实现前后端分离的单点登录问题。

登录实现

1、基于session来实现(单体应用下)

基于session实现登录验证

2、基于session实现登录的问题(单点登录问题的解决方式)

首先出现的问题是:
上述是单体会话信息保存在seesion中,session存在服务器端(session的工作原理图见:),如果是仅仅后端只是针对一个web服务器,上述的方法就可以实现了。但是如果处于web服务器集群的环境下(Nginx做负载均衡,后端部署了两个web服务器,使用轮询等这种请求分配策略),就会出现用户A在服务器1登陆了,但是session存在服务器1中,但是第二次请求被分配到了服务器2中,服务器2内存中没有用户1的session会话导致用户A需要再次登录,这也就设计到解决的单点登录(SSO)的问题:
解决这个问题目前学习到的有两个方法(no session设计):

2.1、jwt方法:

生成并发给客户端之后,后台是不用存储,客户端访问时会验证其签名、过期时间等再取出里面的信息(如username),再使用该信息直接查询用户信息完成登录验证。jwt自带签名、过期等校验,后台不用存储,缺陷是一旦下发,服务后台无法拒绝携带该jwt的请求(如踢除用户)

2.2、token+redis token+redis:

token是自己生成个10位的key,value为用户信息,访问时判断redis里是否有该token,如果有,则加载该用户信息完成登录。服务需要存储下发的每个token及对应的value,维持其过期时间,好处是随时可以删除某个token,阻断该token继续使用.
这两种方式都有自己的优缺点,在这里选择的是redis+token这种方法。
(redis是部署在独立的服务器上,各个web服务器都可以访问到)

2.2.1基于redis+token实现集群下登录注册的功能。

1、功能流程图
token+redis实现登录
使用电话号码作为key,验证码作为value,使用redis中string结构进行存储
随机生成十位字符串作为token,作为key进行存储,value是用户信息。
实现过程中注意的地方
1、选用什么样的redis中的数据结构进行存储:
String结构VSHahs结构

2、存储粒度问题
为什么要进行一个redis存储粒度的划分
(1)、安全性
因为User中有手机号,密码等等涉及用户数据安全的数据,然后如果全部存在redis中,内存存储可能导致数据安全性的问题
(2)、内存问题
因为如果User中全部属性要进行存储的话,会增加内存的压力,这里redis存储用户信息,是为了知道有这个用户,以及之后登录验证的时候明确是哪一个用户在登录操作,所以存储的就是UserId(只要有UserId就可以在后面需要获取用户更多信息进行查询),昵称,头像信息即可。(UserDTO类)
实现过程:
1、User属性赋值到UserDTO对象
使用hutool工具类,来进行
2、存储过程:
使用redis中hash结构来进行

//void putAll(H key, Map<? extends HK, ? extends HV> m);
//第二参数需要的是map,所以要要把对象转换成hashmap
stringRedisTemplate.opsForHash().putAll()

对象转换成hashmap
注意StringRedisTemplateredis需要转换成的map的各个字段都是String类型,而bean的每个属性的类型各不相同(所以要把每个字段的值来进行转换一下,都转换成了string)
使用hutool工具类进行一个值字段类型的转换的转换

Map<String,Object> usermap = BeanUtil.beanToMap(userDTO1,new HashMap<>(),
                CopyOptions.
                        create().
                        setIgnoreNullValue(true)//忽略空值
                        .setFieldValueEditor((fieldName,fieldValue)->fieldValue.toString()));

因为我是第一次接触使用这个hutool工具类,在写进这个项目之前进行了一下测试,发现这个setIgnoreNullValue(true)这个并没有起作用,就是传出的对象中的某个属性,我偷懒设置成了null之后,发现,就报了空指针的错误,debug之后,发现是它并没有忽略掉,导致后面的toString()就报错了。然后我上网查了一下,找到作者在gitee上的回答
作者的回答gitee

1、setFieldValueEditor优先级要高于ignoreNullValue导致前者首先被触发,因此出现空指针问题。你在setFieldValueEditor中也需要判空。

2、这么设计的原因主要是,如果原值确实是null,但是你想给一个默认值,在此前过滤掉就不合理了,而你的值编辑后转换为null,后置的判断就会过滤掉。
然后作者提供了思路就是,在setFieldValueEditor上也要判空,改了一下代码。

转换成hashmap之后,进行存储,之后还要设置过期时间

2.2.2基于redis+token实现集群下登录验证的功能。

    上面已经实现了登录验证功能,然后现在要实现登录验证(会话跟踪:HTTP是无状态的,要记录知道是那一个用户登录,然后之后的页面的跳转)
    以及因为上面还设置了过期时间(过期之后就会从redis中删掉,如果一个用户在app的访问时间长,就会出现会查数据库次数多,避免这个问题,就设计如果该用户一直有访问请求就刷新token的过期时间,所以可以在拦截器中实现这个功能。

使用拦截器
创建了两个拦截器
第一个拦截器(拦截所有路径):获取前端请求携带的token,从redis中查询出来用户的信息,保存到Threadlocal,并且刷新token的过期时间。无论查出来没有都进行一个放行的操作。
在实现这个拦截器的时候,一定要在afterCompletion,进行Threadlocal的移除否则会造成内存泄漏(这个Threadlocal去补课一下,之前学的时候没认证)
第二拦截器:是针对需要登录的路径进行拦截。
最后就是把拦截器注册到mvc的配置中即可(注意顺序)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
根据引用的信息,黑马点评项目的前端部分是部署在nginx服务器上的。然而,关于具体的前端代码没有提供相关的信息。所以,无法直接回答关于黑马点评项目前端代码的问题。请提供更多具体的信息,以便能够给出准确的答案。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [黑马点评详细总结(问题 + 踩坑点 + 解决思路)](https://download.csdn.net/download/qq_59957669/87911791)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [黑马点评项目全部功能实现及详细笔记--Redis练手项目](https://blog.csdn.net/giveupgivedown/article/details/128723748)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [springboot-redis-mysql-nginx项目黑马点评开发(更新中)](https://blog.csdn.net/qq_56750103/article/details/127477499)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值