【电商项目】测试 认证功能 遇到的问题与解决方案
目录
在测试之前可以保留鉴权注解 @PreAuthorize 。
此处给生疏的小伙伴解释一下,对接口进行鉴权配置,用户拥有权限才能访问接口,@PreAuthorize作用就是用来校验当前登录用户有没有指定权限 / 角色,没有就直接拦截,不让进入接口方法。测认证(登录)时,只验证能不能登录成功,不校验权限,注解不影响登录流程。
因为之前对增删改查的测试,数据库包含了脏数据。测试之前,我清空了管理员表,管理员角色表,角色表,角色权限表,权限表,通过这次测试重新添加数据并排查bug。(这是重点,一会要烤)
一、测试类运行报错(程序包不存在,Java找不到符号)
首先我们需要手动添加一个管理员。因为五张表已经全部清空了,我们没有办法登录到内部去操作数据。在认证授权的代码中,我们对密码进行了BCryptpasswordEncoder加密,所以注意 数据库中添加的管理员密码 应为加密后的数据,添加数据保存后会自增id。
我们通过测试类来去获取密文。完成后运行,出现了下面的报错。(程序包***不存在,Java找不到符号(符号:类 SpringBootTest))

可能最大原因有以下几种:
- 缺少 JUnit5 测试依赖 项目 pom.xml 没引入
spring-boot-starter-test测试起步依赖。 - SpringBootTest 导入包版本错乱
- Maven 依赖未刷新 引入依赖后没刷新 Maven、没重新导入,IDEA 本地依赖缓存失效。
- 测试目录结构不规范
小编排查后发现我属于测试目录结构不规范 + 目录标识缺失双重问题:
我的源代码目录是一个 java 目录,不是整个项目,在源代码目录里面测试类无法运行。
所以 Maven 的test作用域依赖不会给这个目录使用,JUnit、SpringTest 类直接找不到
操作是右上角小齿轮打开项目结构,把整个项目勾选为源:

正常已经没有问题了,但是测试时还是报错了,显示密码不对,后来一看是忘实例化 BCryptpasswordEncoder 对象了,这里打上断点是为了看得清楚,重新弄完记得给数据库的错误密文修改了。

二、测试出现错误报错
2.1 未关闭CSRF防护
开启CSRF防护(默认开启,需手动关掉)就会报403异常。
403 代表你账号登录身份是有效的,但服务端判定这次 POST、PUT 这类改数据的请求是伪造的跨站恶意请求,开启 CSRF 校验后缺少防伪 token 就直接拒绝放行,所以返回权限禁止的403。

喜欢思考的小伙伴这时候就有疑问了(比如我):那如果真的是跨站恶意请求,CSRF关了,那不就完蛋了吗,我们后续开发会给这个打开?
首先啊这个完蛋想得没错,关闭 CSRF 等于放弃了跨站伪造请求防护,黑客可以借助你已登录的浏览器 Cookie,在第三方恶意页面直接调用你的修改、删除、提交接口,在你不知情的情况下篡改账号数据。
不过,这是一个前后端分离项目,它是直接永久关闭 CSRF的。
因为前后端分离项目用 Token(JWT)做身份校验,不存在 Cookie 盗用发起跨站请求的条件,CSRF 防护完全多余,还徒增接口调试麻烦。
补充一点针:传统服务端渲染页面(Thymeleaf/JSP 页面)是必须开启 CSRF。 这种的页面由后端渲染,表单自动携带 csrf 令牌,能直接挡住跨站表单伪造攻击。
2.2 resultMap和resultType
依旧报错,首先我确定用户名和密码一定是正确的哈。

报错信息如下:

解释:很直接就能看出来是映射文件有问题,它要把permission封装成一个resultMap,但permission是resultType。
已修改后加黄标注:

这里给模糊的小伙伴区分一下这俩货(虽然图示已经很清晰了):
ResultType
直接指定实体类全路径,字段与实体同名直接映射,简单单表查询用。写法最简,但无法处理关联集合、别名自定义映射。
ResultMap
手动配置映射,自定义字段与实体属性对应关系,支持一对一、一对多 collection 嵌套关联查询,适配字段错位、一对多嵌套查询,可复用映射配置。
2.3 空指针
其他都是边角料,这个才是我最想反馈出来的问题。这和开头清空五张表有关系。

意思非常明确: permissions 集合集合里包含了 null 空元素。当我们尝试对这个空元素调用 .getUrl() 方法,抛出空指针异常 NullPointerException
说白了就是没数据呗。
排查建议:集合中出现 null 元素,通常意味着业务逻辑或数据库查询存在问题。
-
检查数据库查询:如果是通过 MyBatis 或 JPA 查询出的
permissions列表,检查 SQL 语句是否使用了LEFT JOIN左连接。左连接在右表没有匹配记录时会产生null行,这可能导致映射到 Java 对象时出现null对象。 -
检查数据组装逻辑:手动往
permissions集合中进行过add(null)的操作。
终于到了激动人心我最想说的part了!聪明的小伙伴已经知道我想说什么了!
开篇小编就说过,我清空了五张表:管理员表!管理员角色表!角色表!角色权限表!权限表!
所以!我们新增的这个用户是没有任何权限的!这就是空指针的原因。
我们需要添加条件判断代码,不为空时再遍历permission。
这里还需要磨叽一下,mybatisPlus封装空集合非常有意思:permissions不为空,而且它这个元素个数不为0,而是1。这里debug给大家看一下:

如图可知:permissions集合个数为1,我有一个元素,该元素为空
所以添加条件判断,不能说permissions为空或者是0。
那我们怎么判断呢,如下图标黄:

判断第一个元素不为空,就可以啦。
改这个报错的时候我这个初出茅庐的小茅庐感觉自己超像这个👇哈哈哈:

更多推荐




所有评论(0)