我正在连接到具有登录资源:/ login的RESTful API。使用他们给我的凭据,它会带来不错的200
。
但是之后尝试访问受保护的资源会给我一个401
(不过,它可以与Firefox插件RESTClient一起使用)。调试后,我发现一些cookie被拒绝是我认为的原因,这是导致我无法进入的原因。
关于它们的警告消息是:
Cookie拒绝了[somename =“ somevalue”,版本0, domain:xyz.org:443 ,路径:/,到期时间:空] 非法的“ domain”属性“ xyz:443”。来源域:“ xyz”
我正在使用Apache HTTP客户端httpcomponents-client-4.5.6
连接到该站点。有什么我可以做的吗?据我所知,唯一困扰的是:443。该API仅可通过https访问。我不知道是否可以使用httpclient更改对网站的访问权限,因此它不再看到域名方面的差异。
我进行了很多搜索,找到了许多有关CookieSpecProviders的过时解决方案,并将CookieSpecs设置为“简单”-但所有这些似乎完全消除了所有cookie。使用这些解决方案后,我的Cookie存储的调试输出始终为空(但警告消息消失了)。
我建立了一个快速而肮脏的孤立示例:
package apitest;
import java.io.IOException;
import org.apache.http.HttpHost;
import org.apache.http.client.CookieStore;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
public class ApiTest {
public static void main(String[] args) {
HttpHost target = new HttpHost("stackoverflow.com", 443, "https");
HttpClientContext context = HttpClientContext.create();
CookieStore cookieStore = new BasicCookieStore();
HttpClientBuilder clientBuilder = HttpClientBuilder.create().setDefaultCookieStore(cookieStore);
CloseableHttpClient httpClient = clientBuilder.build();
HttpGet stackGet = new HttpGet("");
CloseableHttpResponse response;
try {
response = httpClient.execute(target, stackGet, context);
printCookies(cookieStore);
} catch (IOException e) {
e.printStackTrace();
}
stackGet = new HttpGet("/tags");
try {
response = httpClient.execute(target, stackGet, context);
printCookies(cookieStore);
} catch (IOException e) {
e.printStackTrace();
}
}
static void printCookies(CookieStore cookieStore) {
for (Cookie c : cookieStore.getCookies()) {
System.out.println(c.getName() + " : " + c.getValue());
}
}
}
有两个连续的GET请求已完成,这将导致正确的行为。 'prov'cookie(应该是某种会话cookie)保持不变。使用上述API所做的相同操作也会导致错误。
答案 0 :(得分:0)
我不知道这是否有必要,但是为了解决这个问题,我根据不同来源的建议创建了一个新的CookieSpec:
EasySpecProvider.class
import org.apache.http.cookie.CookieSpec;
import org.apache.http.cookie.CookieSpecProvider;
import org.apache.http.protocol.HttpContext;
class EasySpecProvider implements CookieSpecProvider {
@Override
public CookieSpec create(HttpContext context) {
return new EasyCookieSpec();
}
}
EasyCookieSpec.class
import org.apache.http.cookie.Cookie;
import org.apache.http.cookie.CookieOrigin;
import org.apache.http.cookie.MalformedCookieException;
import org.apache.http.impl.cookie.DefaultCookieSpec;
class EasyCookieSpec extends DefaultCookieSpec {
@Override
public void validate(Cookie arg0, CookieOrigin arg1) throws MalformedCookieException {
}
}
我通过
注册了Registry<CookieSpecProvider> r = RegistryBuilder.<CookieSpecProvider>create()
.register("easy", new EasySpecProvider()).build();
和
clientBuilder.setDefaultCookieSpecRegistry(r)
.setDefaultRequestConfig(RequestConfig.custom().setCookieSpec("easy").build())
进入客户端构建器。之后,所有格式错误的Cookie均被接受,但会话Cookie随每个请求而更改。我想同样的事情然后发生在API的服务器上(cookie的域部分不匹配)。现在,我在每个请求上清除cookie存储,并使用正确的domain属性手动重新创建会话cookie,现在它可以工作了。