应该在API处理程序之前调用OPTIONS请求处理程序

时间:2019-04-28 10:25:13

标签: java spring-boot request cors

我有一个有效的@RestController组件,可以产生API Web端点。

这是这些端点之一

  @CrossOrigin
  @GetMapping(API_VERSION + PLAYER + METHOD_FETCH + "/{uid:^[0-9]*$}")
  public Player fetchPlayer(@PathVariable("uid") String uid) {
    return mongoTemplate.findById(uid, Player.class);
  }

现在使用我的Vue.js应用程序时,我将此端点称为。问题是axios HTTP客户端库将具有身份验证标头的 get 请求转换为 options 请求,以探测服务器的实际访问权限。

现在,我需要使用此 options 请求,并为 CORS 启用该请求。因此,我做了以下事情:

@RestController
@Log
@RequestMapping("/**")
public class AuthenticationEndpoint {
  @CrossOrigin
  @RequestMapping(method = RequestMethod.OPTIONS)
  public void handleOptionRequest(){
    log.info("option request handled");
  }
}

我将其映射到每个URL,因此它“应该”拦截每个OPTIONS请求。但事实并非如此。拥有

GET http://{{host}}:80/api/v0.1/player/fetch/4607255831
Authorization: Basic MTIzNTM2NDMyNDphYmMxMjM=

更具体的API网络终结点是在OPTIONS处理程序之前 处理的。 在Spring MVC中,我怎样才能真正将OPTIONS处理程序放在其他处理程序之前? 我希望它像拦截器一样

OR

实现所需行为的最佳实践方法是什么?我有点觉得我正在寻找更好的解决方案。

1 个答案:

答案 0 :(得分:0)

  

在Spring MVC中,如何实际上将OPTIONS处理程序放在其他处理程序之前?我希望它充当拦截器。

您可以创建一个实现Filter接口的类的组件,并为其赋予高阶:

@Component
@Order(1)
public class RequestInterceptor implements Filter {

    @Override
    public void doFilter
      ServletRequest request, 
      ServletResponse response, 
      FilterChain chain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        String httpMethod = req.getMethod();
        if(HttpMethod.OPTIONS.name().equals(httpMethod)){
           //do something here before reaching the method handler
        }
        chain.doFilter(request, response);

    }

    // other methods 
}

或者您可以扩展OncePerRequestFilter.java并在doFilterInternal方法中进行与上述相同的检查。


编辑

如果您想控制是否继续处理给予请求,可以使用HandlerInterceptor

  

在适当的HandlerAdapter之前调用HandlerInterceptor   触发处理程序本身的执行。这种机制可以是   用于大量的预处理方面,例如对于   授权检查,或常见的处理程序行为,如语言环境或主题   变化。其主要目的是允许排除重复   处理程序代码。

     

HandlerInterceptor基本上类似于Servlet   过滤器,但与后者相反,它仅允许自定义   预处理,可以选择禁止执行   处理程序本身,以及自定义的后处理。过滤器功能更强大,   例如,它们允许交换请求和响应对象   传下来的链条。请注意,在   web.xml,即应用程序上下文中的HandlerInterceptor。

@Comonent
public class LoggerInterceptor extends HandlerInterceptorAdapter {
     @Override
     public boolean preHandle(HttpServletRequest request,
                          HttpServletResponse response,
                          Object handler)
                   throws Exception{
         // do checks and decide wether to complete or to stop here
         // true if the execution chain should proceed with the next interceptor or the handler itself. 
        // Else, DispatcherServlet assumes that this interceptor has already dealt with the response itself.
        return true;
     }
     // other methods
}