背景:
我这边需要拦截一下token,写了一个过滤器,出现了一个情况前端传过来的有token,但是后端处理的时候会出现null的情况。
场景复现:
前端请求含有token
但是后端总是有
并且报错403
这里,我就搜了一下预检(可以不看)从前后端的角度分析options预检请求——打破前后端联调的理解障碍-腾讯云开发者社区-腾讯云 (tencent.com)https://cloud.tencent.com/developer/article/2281002
如果带有自定义的标头会发送一个预检请求,预检请求会不含有token标头。所以说应该参考这里修改。
解决方案:
修改方法如下:
实际上发送了两次请求,第一次为 OPTIONS 请求,第二次才 GET/POST… 请求
在OPTIONS请求中,不会携带请求头的参数,所以在拦截器上获取请求头为空,自定义的拦截器拦截成功
第一次请求不能通过,就不能获取第二次的请求了 GET/POST…
第一次请求不带参数,第二次请求才带参数
原因是发送了两次请求,一次预检一次完整的请求,预检不带token标头,所以说会为null,修改一下即可。
由于我没有使用true,修改代码如下:
if (HttpMethod.OPTIONS.toString().equals(((HttpServletRequest) request).getMethod())) {
System.out.println("OPTIONS请求,放行");
filterChain.doFilter(request,response);
return;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.setCharacterEncoding("UTF-8");
if (HttpMethod.OPTIONS.toString().equals(httpServletRequest.getMethod())) {
System.out.println("OPTIONS请求,放行");
filterChain.doFilter(request,response);
return;
}
//获取url
String url = httpServletRequest.getRequestURI();
System.out.println("拦截url: "+url);
//判断是否包含login请求,是就放行
if (url.contains("login") || url.contains("refreshToken")) {
filterChain.doFilter(request,response);
return;
}
//获取token
String Authorization = httpServletRequest.getHeader("Authorization");
System.out.println("Authorization: " + Authorization);
if (!StringUtils.hasLength(Authorization)) {
return;
}
String token = Authorization.split(" ")[1];
System.out.println("穿过来的token: " + token);
filterChain.doFilter(request,response);
}