认证_校验
- 一、认证过滤器
- 二、配置过滤器
- 三、测试过滤器
- 3.1 登录接口
- 3.2 非登录接口
- 3.3 结果
- 一键三连有没有捏~~
一、认证过滤器
创建一个filter包,创建一个过滤器
代码如下:
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {@Autowiredprivate RedisTemplate redisTemplate;@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws ServletException, IOException {//获取tokenString token = request.getHeader("token");if (!StringUtils.hasText(token)) {//放行filterChain.doFilter(request, response);return;}//解析tokenString userid;try {Claims claims = JwtUtil.parseJWT(token);userid = claims.getSubject();} catch (Exception e) {e.printStackTrace();throw new RuntimeException("token非法");}//从redis中获取用户信息String redisKey = "login:" + userid;LoginUser loginUser = (LoginUser) redisTemplate.opsForValue().get(redisKey);if (Objects.isNull(loginUser)) {throw new RuntimeException("用户未登录");}//存入SecurityContextHolder//TODO 获取权限信息封装到Authentication中UsernamePasswordAuthenticationToken authenticationToken =new UsernamePasswordAuthenticationToken(loginUser, null, null);SecurityContextHolder.getContext().setAuthentication(authenticationToken);//放行filterChain.doFilter(request, response);}
}
一些疑问解答:
为什么过滤器不实现filter呢?
因为在不同的servlet版本当中,可能会导致一个请求过来,会被调用多次,所以我们使用spring为我们提供的一个实现类OncePerRequestFilter实际上对于认证这样的有关安全操作每个请求也应该是只应该执行一次
为什么使用三个参数的构造方法?
一种是有两个参数的:传递用户名跟密码就可以了
一种是有三个参数的:在三个参数的里面,它有一个set方法,authenticate获取真实性,代表你是否是一个已认证的状态,流程走到这里,肯定是已经认证过的了,所以使用有三个参数的方法。第一个传的是用户的信息,第二个是null,第三个是权限的信息,目前还没有权限信息,所以也写null。
SpringSecurity后面执行的过滤器会去SecurityContextHolder中获取信息,所以在放行之前要将信息存入SecurityContextHolder
二、配置过滤器
完成过滤器之后,我们要去指定一下过滤器的位置,在哪里进行过滤,我们把它放在UsernamePasswordAuthenticationFilter之前的位置
代码如下:
三、测试过滤器
3.1 登录接口
然后,我们先使用我们的postman测试一下登录接口
现在,我们的登录接口,请求头是没有token的
看一下,我们的idea,已经到断点这里了
下一步,没有token,所以为null
然后就直接让他放行就可以了
3.2 非登录接口
用一个不是登录的接口的测试一下
然后,一直放行,放行到后面,肯定是一个认证失败的结果
认证失败
我们想让他访问成功,就把之前登录成功的token拿过来,作为请求头,就可以了。
3.3 结果
项目重新启动了之后,老token就不能登录了,必须重新登录,要新的token
老token不能访问,新登录的token可以访问
老token登录报错了,报的是语法错误,乱码了