Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
20
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

@YukiAsu

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

前回までのあらすじ

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

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
20
Help us understand the problem. What are the problem?