使用存储在 persistentcookiejar 或其他容器中的 Cookie 来处理 android 中的 okhttp 请求
Posted
技术标签:
【中文标题】使用存储在 persistentcookiejar 或其他容器中的 Cookie 来处理 android 中的 okhttp 请求【英文标题】:Use stored Cookie in persistentcookiejar or some other container for okhttp requests in android 【发布时间】:2020-06-03 19:09:56 【问题描述】:这个问题基本上是想知道如何使用存储的cookies进行后续请求。下面的长文只是举例。 基本问题是如何对特定网站上的所有请求使用相同的 cookie。
基本上,我试图在 android 应用程序中访问网站的登录页面。该网站的工作方式如下。
有 3 个网址需要考虑。
1 -> "http://www.example.com/timeoutPage"
2 -> "http://www.example.com/mainPage"
3 -> "http://www.example.com/loginPage"
要考虑的两个要点是
(1) 如果我们直接去第三个url(loginPage),它会重定向到第一个url(timeoutPage)。 timeoutPage 有一个按钮可以转到 mainPage。
(2) 如果我们转到第二个 url (mainPage),它会给我们一个 cookie。现在,在获取 cookie 后,当我们访问第三个 url(loginPage)时,我们就可以访问它了。 loginPage 有一个验证码,因此必须访问它(loginPage)才能登录。
如果没有访问 2nd url(mainPage) 时给出的 cookie,我们无法直接访问 3rd url(loginPage)。
所以我要做的是制作一个 ClearableCookieJar 并将它附加到 OkHttpClient。
OkHttpClient client;
ClearableCookieJar cookieJar;
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
cookieJar = new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(this));
client = new OkHttpClient.Builder()
.cookieJar(cookieJar)
.build();
Request request = new Request.Builder()
.url("http://www.example.com/mainPage")
.build();
client.newCall(request).enqueue(new Callback()
@Override
public void onFailure(Call call, IOException e)
e.printStackTrace();
textView.setText("Failed to get response");
@Override
public void onResponse(Call call, Response response) throws IOException
if(response.isSuccessful())
final String myResponse = response.body().string();
MainActivity.this.runOnUiThread(new Runnable()
@Override
public void run()
textView.setText(myResponse);
);
);
到这里为止一切都很好,因为我可以在我的 textview 中打印 mainPage 的 html。 当我再次请求 loginPage 时,问题从这里开始。
request = new Request.Builder()
.url("http://www.example.com/loginPage")
.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0")
.build();
client.newCall(request).enqueue(new Callback()
@Override
public void onFailure(Call call, IOException e)
e.printStackTrace();
textView.setText("Failed to get response");
@Override
public void onResponse(Call call, Response response) throws IOException
if(response.isSuccessful())
final String myResponse2 = response.body().string();
MainActivity.this.runOnUiThread(new Runnable()
@Override
public void run()
textView.setText(myResponse2);
);
);
在这里我再次向 loginPage 发出请求,但我到达了 timeoutPage。我应该如何请求 loginPage url,以便我的请求在向 mainPage 发出请求时发送我存储在 cookieJar 中的 cookie。我想到的一种方法是
request = new Request.Builder()
.url("http://www.example.com/loginPage")
.addHeader("Cookie", cookieStringGivenAtMainPage)
.build();
但我不知道如何访问该 cookieStringGivenAtMainPage。我应该如何到达该 loginPage?
我打印响应的 html,看看我是否到达了正确的页面。
【问题讨论】:
【参考方案1】:看来您想知道的答案是单例模式。 请参考下面的示例代码。大约 3 年前,我从 kakao 开发者网站获得了它。
public class NetworkManager
private static NetworkManager instance;
private OkHttpClient client;
/**
* By using Singleton Pattern we can share cookie, client values.
**/
private NetworkManager()
OkHttpClient.Builder builder = new OkHttpClient.Builder();
Context context = GlobalApplication.getGlobalApplicationContext();
ClearableCookieJar cookieJar = new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(context));
builder.cookieJar(cookieJar);
builder.followRedirects(true);
builder.addInterceptor(new RedirectInterceptor());
File cacheDir = new File(context.getCacheDir(), "network");
if (!cacheDir.exists())
cacheDir.mkdir();
Cache cache = new Cache(cacheDir, 10 * 1024 * 1024);
builder.cache(cache);
builder.connectTimeout(30, TimeUnit.SECONDS);
builder.readTimeout(10, TimeUnit.SECONDS);
builder.writeTimeout(10, TimeUnit.SECONDS);
client = builder.build();
public static NetworkManager getInstance()
if (instance == null)
instance = new NetworkManager();
return instance;
public OkHttpClient getClient()
return client;
以下是示例用法。
OkHttpClient client = NetworkManager.getInstance().getClient();
RequestBody formBody = new FormBody.Builder()
.add("userId", getTargetUserId())
.build();
Request request = new Request.Builder()
.url("www.test.com/insert.php")
.post(formBody)
.build();
client.newCall(request).enqueue(callback);
【讨论】:
以上是关于使用存储在 persistentcookiejar 或其他容器中的 Cookie 来处理 android 中的 okhttp 请求的主要内容,如果未能解决你的问题,请参考以下文章
是否可以使用密钥保管库加密文件并使用“Azure 存储数据移动库”将其存储在存储帐户中