泽西过滤器不提供标头值

时间:2018-05-08 11:09:22

标签: java rest web-services jersey-2.0

我们使用jersey 2作为Java中的REST Web服务。 我们创建了javax.ws.rs.container.ContainerRequestFilterjavax.ws.rs.container.ContainerResponseFilter

我们在发送appKey,secret,token等请求时有标题。 如果我们点击Postman的请求,它会为所有标题提供其值,如下所示:

{
  host=[localhost:8080], 
  connection=[keep-alive], 
  authorization=[bearer <token>], 
  cache-control=[no-cache],  
  x-request-id=[<request-id>], 
  x-api-secret=[<secret>], 
  user-agent=[Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36], 
  x-api-key=[api-key], 
  postman-token=[<postman-token>], 
  accept=[*/*], 
  accept-encoding=[gzip, deflate, br], 
  accept-language=[en-US,en;q=0.9]
}

如果我们点击了来自我们网络客户端的请求,它会在access-control-request-headers下提供如下值(仅键,而不是其值):

{
  host=[localhost:8080], 
  connection=[keep-alive], 
  access-control-request-method=[GET], 
  origin=[http://resttesttest.com], 
  user-agent=[Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36], 
  access-control-request-headers=[authorization,x-api-key,x-api-secret,x-request-id], 
  accept=[*/*],
  accept-encoding=[gzip, deflate, br],
  accept-language=[en-US,en;q=0.9]
}

为什么它不提供标题参数值?

如何获得这些?

请指导我。 提前谢谢!

1 个答案:

答案 0 :(得分:2)

首先,这些是您正在显示的请求标头,而不是响应标头,您似乎在说它们。

您在此处显示的是CORS preflight请求中的标头,而不是实际请求。预检请求是浏览器在实际请求之前执行的请求,向服务器验证是否允许该请求。如果预检被批准,那么将提出真实的请求。在预检中,浏览器询问服务器是否允许列出的标题。这位于请求标头access-control-request-headers中。同样,它使用access-control-request-method询问服务器是否允许GET方法调用。

在对CORS预检请求的响应中,服务器应使用标头响应,确认请求是可接受的。响应应包括以下标题

  • Access-Control-Allow-Origin - 这是对Origin预检请求标头的回复。该值应包括Origin的值或*以允许所有来源。这告诉浏览器允许原点。

  • Access-Control-Allow-Headers - 这是对access-control-request-headers预检请求标头的回复。该值应该是至少浏览器请求的所有标头的逗号分隔列表。如果缺少任何一个,预检请求将失败。

  • Access-Control-Allow-Methods - 这是对access-control-request-method预检请求标头的回复。该值至少应为所请求的方法,或者通常是允许的方法列表。

如果您查看this post,您会看到ContainerResponseFilter用于处理此预检请求的返回,方法是添加所有必需的标题以传递预检验证。

@Provider
public class CORSFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext request,
                       ContainerResponseContext response) throws IOException {

        response.getHeaders().add("Access-Control-Allow-Origin", "*");
        response.getHeaders().add("Access-Control-Allow-Headers",
                "origin, content-type, accept, authorization");
        response.getHeaders().add("Access-Control-Allow-Credentials", "true");
        response.getHeaders().add("Access-Control-Allow-Methods",
                "GET, POST, PUT, DELETE, OPTIONS, HEAD");
    }
}

在您的情况下,您需要将标题x-api-key,x-api-secret,x-request-id添加到Access-Control-Allow-Headers的列表中。这些值告诉浏览器发送这些标题是可以的。

预检请求成功后,浏览器将发送实际请求。如果预检失败,那么浏览器通常会给出一个关于哪些验证失败的提示。