LoginSignup
21

More than 5 years have passed since last update.

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

Posted at

前回までのあらすじ

以前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が取得できないんだろう?
もうだいぶ昔の話で表題のバグはなおってるっぽいけれど、中の動きがよくわかった。(気がする)

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21