我正在使用 Retrofit (1.7.1),它使用默认的 OkHttp (2.1.0) 客户端(我猜)在服务器上进行身份验证,并获取一些 session cookie 来回复每个其他请求。
我有一个 CookieManager 和一个设置“Cookie” header 的拦截器。
拦截器将 cookie 构建为
cookieName + "=" + cookieValue + "; "
(我实际上使用了 StringWriter 但结果是一样的)
正确的 header 结果应该是:
Cookie: PHPSESSID=<my_php_sess_id>; session=<my_session_id>;
但是
默认实现(我猜是 OkHttp)添加了另一个 Cookie header ,结果是:
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>"
我发现第二个 header 仅使用 WireShark 检查网络数据包,所有库日志仅显示第一个 header 。
我认为第二个 header 会引起一些麻烦:请注意 cookie 值周围的引号。
有没有办法告诉 OkHttp 或 Retrofit 使用“普通”版本的 cookie?
也许我误解了整个 Cookie/Client/Interceptor 机制,但将 Retrofit 客户端设置为:
.setClient(new ApacheClient(new DefaultHttpClient()))
解决了问题。
最佳答案
我遇到了类似的问题,是由不处理版本 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)
>.
关于java - 如何在OkHttp中设置cookie格式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26080988/