【对非登陆请求过滤,验证token】四步

**
 * 对非登陆请求过滤,验证token
 *
 * 1:判断请求头里是否携带token。请求时候怎么在请求头里携带jwt?怎么拿token里的jwt?
 *      没带,交给后面过滤器处理
 *      如果有,走第2步
 *
 * 2:判断token的合法性。即decode是否能解开。
 *      不合法:交给后面过滤器处理
 *      合法:走到第3步
 *
 * 3:判断 redis token 是否过期
 *      过期:交给后面过滤器处理
 *      没过期:走到第4步
 *  
 *  4:判断请求头里的 token 是否等于 redis里的 存的 token,即是否是当前用户的token
 *      不一样:交给后面过滤器处理
 *      一样:给 token 续期

@Component
public class JWTFilter extends OncePerRequestFilter {
    
    @Autowired
    private RedisTemplate<String,Object>redisTemplate;

    @Autowired
    SecurityService securityService;
    
    @SneakyThrows
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //第一步
        String token = request.getHeader("token");
        if(token==null){
            filterChain.doFilter(request,response);
            return;
        }
        //第二步
        if(!JWTUtil.decode(token)){
            filterChain.doFilter(request,response);
            return;
        }
        
        Map userInfo = JWTUtil.getUserInfo(token);
        String userId = String.valueOf(userInfo.get("userId"));
        //第三步
        
        String redisToken = (String) redisTemplate.opsForValue().get("token:"+userId);
        if(redisToken==null){
            filterChain.doFilter(request,response);
            return;
        }
        
        //第四步
        if(!token.equals(redisToken)){
            filterChain.doFilter(request,response);
            return;
        }
        redisTemplate.opsForValue().set("token:"+userId,token,30, TimeUnit.MINUTES);
        filterChain.doFilter(request,response);
    }
}

还没完,接下来还有一步。

因为security框架默认是通过session方式记录登陆状态,可能会对jwt产生干扰,所以 我们要禁掉session 并用唯一的jwt方式登陆。
在security.config类加一行
//前后端项目中要禁用掉session
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
在禁掉session后 没有了登陆凭证 ,所以当对方经过了一系列校验之后,我们要在security容器中,手动放入登陆凭证。
 //第五步 放入登陆凭证

/**
* UsernamePasswordAuthenticationToken是一种登陆凭证
*/
    UserDetails userDetails = securityService.loadUserByUsername((String)userInfo.get("accont"));
    UsernamePasswordAuthenticationToken upa = 
    new UsernamePasswordAuthenticationToken( userDetails.getUsername(),
    userDetails.getPassword(),
    userDetails.getAuthorities());
    SecurityContextHolder.getContext().setAuthentication(upa);
    filterChain.doFilter(request,response);

然后再去security.config类注册 

http.addFilterAfter(jwtFilter, UsernamePasswordAuthenticationFilter.class);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员大雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值