一、引出问题
上节我们实现了登录校验的功能,但还是有一些小问题,登录校验的功能返回的信息有点多,但其实我们做登录用户的时候,其实只要返回用户的id、名称、头像等信息就够了,像时间、密码、电话这些敏感信息就没必要返回,因此这是有泄漏风险的。
返回这么多信息的原因是我们返回的是User对象
那么UserHolder信息又从哪来?就是我们当时做的拦截器,从session中取出来后二话不说就扔进UserHolder中了,也就是说从session中取出来的就是完整的信息。
session是tomcat的内存空间,你在这里面存的信息越多,对整个服务来讲压力也就越大,因此这里面存那么多不相关 / 不重要的信息没必要。
那么是谁存到session中的呢?是我们在做登录业务的时候,查询或者创建出来的对象二话不说直接就扔到session中了。
因此,从一开始我们存入session的就不应该是完整的信息,而是部分信息。这其实就是一个存储力度的问题,存储的越完整,使用起来肯定更方便,但是带来的问题就是内存压力过大,还有一些敏感信息也返回给前端了。
因此需要改正,那么怎么改正呢?
二、解决办法
采用的核心思路就是书写一个UserDto对象,这个UserDto对象就没有敏感信息了,我们在返回前,将有用户敏感信息的User对象转化成没有敏感信息的UserDto对象,那么就能够避免这个尴尬的问题了
UserDTO.java
package com.hmdp.dto;
import lombok.Data;
@Data
public class UserDTO {
private Long id;
private String nickName;
private String icon;
}
在登录方法处修改
那么怎么转成UserDto呢?笨方法就是一个手动new一个Dto,然后手动存进去就行了。但是在这我们有一个工具类 BeanUtil
,这个也是hutool里面的工具类,它里面有一个方法叫 copyProperties
,意思就是拷贝属性,第一个参数是数据源,第二个参数是目标,目标可以给一个具体的对象,也可以给class字节码。这个方法就会自动的帮我们把User中所有的属性拷贝到UserDto中,而且要给你创建出对象,因此这个方法的返回值就是UserDto。
PS:区分于spring提供的BeanUtils
//7.保存用户信息到session中
session.setAttribute("user", BeanUtil.copyProperties(user,UserDTO.class));
在拦截器处:
//5.存在,保存用户信息到Threadlocal
UserHolder.saveUser((UserDTO) user);
在UserHolder处:将user对象换成UserDTO
public class UserHolder {
private static final ThreadLocal<UserDTO> tl = new ThreadLocal<>();
public static void saveUser(UserDTO user){
tl.set(user);
}
public static UserDTO getUser(){
return tl.get();
}
public static void removeUser(){
tl.remove();
}
}
然后在用到 getUser()
的地方就需要全部修改了,选中方法,然后 alt + F7 可以看见方法在哪些地方用到了。
用到了 getUser()
方法的地方都需要修改。
三、测试
重启项目,然后重新登陆,查看用户信息,可以发现只剩下三个字段了。