报错信息:
点到出问题的文件,debug
是下面这一句出现的问题
携带token时,authentication.getPrincipal()打印出来是一个对象
不携带token时,只是一个字符串
自然 字符串 不能强转成一个 对象 了
要想不报错,以上这么写在post时必须携带token
不然就加个if的判断,给他放行(不建议)
知识扩展:
/**
* 登录校验过滤器 JwtAuthenticationTokenFilter
*/
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
@Autowired
private RedisCache redisCache;
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
//获取请求头中的token
String token = httpServletRequest.getHeader("token");
if (!StringUtils.hasText(token)){
//说明该接口不需要登录 直接放行
filterChain.doFilter(httpServletRequest,httpServletResponse);
return;
}
//解析获取userId(解密)
Claims claims = null;
try {
claims = JwtUtil.parseJWT(token);
} catch (Exception e) {
//token超时 token非法,
e.printStackTrace();
//响应告诉前端需要重新登录
ResponseResult result = ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
WebUtils.renderString(httpServletResponse, JSON.toJSONString(result));
return;
}
String userId = claims.getSubject();
//从redis中获取用户信息
LoginUser loginUser = redisCache.getCacheObject("bloglogin:" + userId);
//如果获取不到
//说明登录过期,要重新登录
if (Objects.isNull(loginUser))
{
ResponseResult result = ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
WebUtils.renderString(httpServletResponse, JSON.toJSONString(result));
return;
}
//存入SecurityContextHolder
//三个参数是认证后状态
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser,null,null);
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
filterChain.doFilter(httpServletRequest,httpServletResponse);
}
}
```java
JwtAuthenticationTokenFilter 这个登录校验过滤器,对于请求,他会先做有没有携带token判断,如果没有放行(后面还有校验),有的话解析token获取userid,验证是否正确后,正确将获取到的对象 存入SecurityContextHolder。
这也就是为什么上面利用 SecurityContextHolder.getContext().getAuthentication().getPrincipal()
能获取到对象LoginUser了