我正在使用Retrofit(1.7.1),它使用默认的OkHttp(2.1.0)客户端(我猜)在服务器上进行身份验证,并获取一些会话cookie来回复其他请求。
我有一个CookieManager和一个拦截器来设置" Cookie"报头中。
拦截器将cookie构建为
cookieName + "=" + cookieValue + "; "
(我实际上使用的是StringWriter但结果却一样)
正确的标题结果应为:
Cookie: PHPSESSID=<my_php_sess_id>; session=<my_session_id>;
BUT
默认实现(我猜是OkHttp)添加了另一个Cookie头,结果是:
Cookie: PHPSESSID=<my_php_sess_id>; session=<my_session_id>;
Cookie: $Version="1"; PHPSESSID="<my_php_sess_id>";$Path="/";$Domain="<my_domain>"; session="<my_session_id>";$Path="/";$Domain="<my_domain>"
我可以找到第二个标头只用WireShark检查网络数据包,所有库日志只显示第一个。
我认为第二个标题会导致一些问题:请注意cookie值周围的引号。
有没有办法告诉OkHttp或Retrofit使用&#34; plain&#34; cookie的版本?
也许我误解了所有的Cookie / Client / Interceptor机制,但将Retrofit客户端设置为:
.setClient(new ApacheClient(new DefaultHttpClient()))
解决了这个问题。
答案 0 :(得分:1)
我有一个类似的问题,由一个没有处理版本1 cookie(引用值)的网络服务器引起。我发现实现这一目标的唯一方法是迭代你的cookie商店:
for (HttpCookie cookie: cookieStore.getCookies()) {
cookie.setVersion(0);
}
但是......每次更改cookie时都需要调用它。我写了一个OkHttp拦截器就是这样做的:
public class CookieBaker implements Interceptor {
private CookieStore cookieStore;
public CookieBaker(CookieStore cookieStore) {
this.cookieStore = cookieStore;
}
@Override
public Response intercept(Chain chain) throws IOException {
for (HttpCookie cookie: cookieStore.getCookies()) {
cookie.setVersion(0);
}
Response response = chain.proceed(chain.request());
for (HttpCookie cookie: cookieStore.getCookies()) {
cookie.setVersion(0);
}
return response;
}
}
这就是你启用它的方式:
OkHttpClient httpClient = new OkHttpClient();
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
httpClient.setCookieHandler(cookieManager);
httpClient.interceptors().add(new CookieBaker(cookieManager.getCookieStore()));
我不使用Retrofit,但你应该用.setClient(new ApacheClient(new DefaultHttpClient()))
之类的内容替换你对.setClient(httpClient)
的号召。