写在前面

因为之前没有系统的看过SpringSecurity,而且之前在写微人事的时候没有采用JWT的认证方式,所以最近打算把SpringSecurity再重新看一遍,顺便熟悉一下怎么使用JWT的认证方式(不知道为什么是重新,之前好像也没怎么看过

demo介绍

简单介绍一下,问题主要出在下面这两个地方

自定义的登录接口

  1. 调用ProviderManager的方法进行认证,如果认证通过生成jwt

  2. 把用户信息存入redis中,这里键值对中的键是"login:" + userid,值即是用户认证信息

认证部分没什么问题就略过不放了,存入redis核心代码如下

LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
String userid = loginUser.getUser().getId().toString();
String jwt = JwtUtil.createJWT(userid);
redisCache.setCacheObject("login:" + userid, loginUser);

定义Jwt认证过滤器

  1. 获取token

  2. 解析token获取其中的userid

  3. redis中获取用户信息

  4. 存入SecurityContextHolder

前面解析也不放了,这里展示从redis读取的代码,后面存入SecurityContextHolder也不是本文的重点

String redisKey = "login:" + userid;
LoginUser loginUser = redisCache.getCacheObject(redisKey);

看似没什么问题对吧

登录也可以正常获取token

image-20230706003211606

出现了问题

在访问接口时认证过滤器报错了,报了个ClassCastException,无法将JSNObject转化为LoginUser

^_^

image-20230706003336360

看一下redis里存储的信息

image-20230706003724792

以为是需要JSON工具来转换一下

String cacheObject = redisCache.getCacheObject(redisKey);
LoginUser loginUser = JSON.parseObject(cacheObject, LoginUser.class);

还是一样,不过这次是无法将JSNObject转化为String

为什么转字符串都转不了有点辣鸡^_^

然后查了一下,存储到redis时,要转换为json字符串进行存储??

于是将之前直接存入的对象先转换为了json

redisCache.setCacheObject("login:" + userid, JSON.toJSONString(loginUser));

成功乐

image-20230706004546947

写在后面

这还没结束,后来我去研究了一下,发现有一个类叫做FastJsonRedisSerializer,说人话就是Redis使用FastJson序列化,然后在RedisConfig中也有用到

FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(Object.class);

发现有一个默认的包,那么问题就出现在这了…

image-20230706010733713

导错包了^_^