最近刚接到手的jwt+shiro的项目整合,发现一直有个问题,token错误后,他会一直在JWTFilter中不断循环,最终报:
java.lang.IllegalStateException: Cannot call sendError() after the response has been committed 如上错误
正因为形成了死循环,导致了response多次的请求,报了这个错误,初步断定,是Filter中有问题,异常没抛出来,进入到JWTFilter中,断点发现确实如此.
try { HttpServletResponse httpServletResponse = (HttpServletResponse) response; //设置编码,否则中文字符在重定向时会变为空字符串 httpServletResponse.sendRedirect("/user/401"); } catch (IOException e) { System.out.println(e.getMessage());很明显,在token失效后,我设置了重定向到/user/401这个接口中的代码没有执行到我想要的目的.可能是ShiroConfig中配置了拦截所有资源导致的, 打开发现
// 所有的请求通过我们自己的JWT filter filterRuleMap.put("/**", "jwt"); // 访问401和404页面不通过我们的Filter,一定只能先放行资源,在拦截资源 filterRuleMap.put("/user/401", "anon"); filterRuleMap.put("/user/404", "anon");果然放行代码是写了,但是因为按照shiro官方的说法,放行的资源要放在拦截的资源前,因此我作出如下修改
// 访问401和404页面不通过我们的Filter,一定只能先放行资源,在拦截资源 filterRuleMap.put("/user/401", "anon"); filterRuleMap.put("/user/404", "anon"); // 所有的请求通过我们自己的JWT filter filterRuleMap.put("/**", "jwt");再次运行,成功通过,也可重定向到错误信息接口.
这个死循环就因为Token无效后,会随着重定向,携带token过去,因为拦截下来,被JWT继续检测到了token,继续拦截,重复解密,然后token继续失效,无限循环,知道里面抛出异常.