Help us understand the problem. What is going on with this article?

Volleyでcookieをちゃんと扱う(あるいはHttpURLConnectionの話)

More than 5 years have passed since last update.

前回までのあらすじ

以前VolleyでCookieとUserAgentをまとめていじりたいとは言ったのだけれど、どうにもcookieの扱いが無理やりすぎてコレジャナイ感があった。実際"responseを拾えばSet-Cookieを回収できる"とは言ったものの、単純なString扱いなので例えばDomainごとに制御したりとかができないのだ。

Volleyの同じQueueで自分のAPIとTwitter両方ともつついたりしてると、双方に双方のCookieを流し込むことになる。そんなの気持ち悪い!なんとかしたい!(というかセキュリティ的にアカン)

HurlStack、あるいはHttpURLConnectionをちゃんと考える

そもそもVolleyを使う為に仕方なくHurlStackを使ってる、という意識だったので理解が薄すぎた。どう考えても標準でCookieを扱う仕組みがあるべきだし、あるだろう。HurlStack方面でそれを調べて見る。

HurlStack。とはいえこいつの中ではHttpURLConnectionを使っているにすぎない。そしてこれにはきちんとCookieを操作するための標準的な仕組みが存在する。それが CookieHandlerCookieManagerだ。

CookieManagerを使えばCookieStoreが取得できる。中身はHttpCookieというのが詰まっていて、もうこれはほぼゴールだ。getName()やgetValue()だけじゃない、getDomain()もできちゃったりしてやりたい放題だ。これに任せよう。

きちんと設定してあげればVolley以外でもHttpURLConnectionを使っている箇所すべてにCookieが染み渡るのも素晴らしい。

RequestQueueに入れてみる

以上の点を踏まえ、前回同様RequestQueueをこう書き換えてみた

RequestQueueWithCookie
// CookieManagerを作ってDefaultに設定
final CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);

// Volleyのリクエストキューを生成
RequestQueue mRequestQueue = Volley.newRequestQueue(getApplicationContext(), new HurlStack(){
    @Override
    public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders)
            throws IOException, AuthFailureError {
        Map newHeaders = new HashMap();
        newHeaders.putAll(additionalHeaders);
        // セッション維持のためcookieとUserAgentを設定する
        newHeaders.put("User-Agent", "ユーザーエージェント");
        // 実際はoldCookieはどこからともなく持ってきてStoreに登録する
        CookieStore store = cookieManager.getCookieStore();
        HttpCookie oldCookie = new HttpCookie("クッキーのname", "クッキーのvalue");
        store.add(URI.create("domain"), oldCookie);

        // responseを待ってCookieを回収する
        HttpResponse response = super.performRequest(request, newHeaders);
        // cookieの回収
        List<HttpCookie> cookies = store.getCookies();
        if (cookies.size() > 0) {
            // あればクッキーを保存
            // cookies.get(0)とかをどうにかこうにか保存します
        }

        return response;
    }
});

これならたぶん有効期限とかもよしなに処理してくれるし、絶対こっちのほうが健全だと思った。

参考

どうしてJaveでCookieが取得できないんだろう?
もうだいぶ昔の話で表題のバグはなおってるっぽいけれど、中の動きがよくわかった。(気がする)

YukiAsu
なぜか毎年別言語に取り組み続ける雑食系エンジニア。ここまで来てなんだけど個人的にはScalaが性に合ってた気がする。 PHP->Objective-C->Swift->AndroidSDK->Scala -> Python -> Ruby -> Go
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした