Как реализовать обработку файлов cookie на Android с помощью OkHttp?

Используя OkHttp by Square https://github.com/square/okhttp, как я могу:

  1. Получить файл cookie, возвращенный с сервера
  2. Сохраните cookie для предстоящих запросов
  3. Использовать сохраненный файл cookie в последующих запросах
  4. Обновите cookie, возвращенный последующим запросом

В идеале файл cookie должен храниться, повторно отправляться и обновляться автоматически при каждом запросе.


person Daniel    schedule 17.06.2014    source источник


Ответы (3)


Для OkHttp3 простая реализация принятия всех, непостоянная CookieJar может быть следующей:

OkHttpClient client = new OkHttpClient.Builder()
    .cookieJar(new CookieJar() {
        private final HashMap<HttpUrl, List<Cookie>> cookieStore = new HashMap<>();

        @Override
        public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
            cookieStore.put(url, cookies);
        }

        @Override
        public List<Cookie> loadForRequest(HttpUrl url) {
            List<Cookie> cookies = cookieStore.get(url);
            return cookies != null ? cookies : new ArrayList<Cookie>();
        }
    })
    .build();

Или, если вы предпочитаете использовать java.net.CookieManager, включите okhttp-urlconnection в свой проект, который содержит JavaNetCookieJar, класс-оболочку, который делегирует java.net.CookieHandler:

dependencies {
    compile "com.squareup.okhttp3:okhttp:3.0.0"
    compile "com.squareup.okhttp3:okhttp-urlconnection:3.0.0"
}

CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
OkHttpClient client = new OkHttpClient.Builder()
    .cookieJar(new JavaNetCookieJar(cookieManager))
    .build();
person hidro    schedule 12.01.2016
comment
Значит, автоматически сохраняется, и мне ничего не нужно делать? После перезагрузки работает? - person Kamil Nękanowicz; 14.01.2016
comment
Нет, это пример для непостоянного файла cookie. Для постоянного решения вы можете реализовать свое собственное, например stackoverflow.com/a/25462286/836540 и оберните его JavaNetCookieJar. - person hidro; 14.01.2016
comment
Кстати, URL-адрес - это «ПОЛНЫЙ URL-адрес» на сервер, и он будет отправлять файлы cookie только при выполнении запроса на тот же URL-адрес. Вы можете заменить cookieStore.put(url, cookies); на cookieStore.put(url.host(), cookies); Для loadForRequest coookieStore.get(url.host());. И заменить HashMap<HttpUrl, List<Cookie>> на HashMap<String, ...> - person Eddie; 18.02.2016
comment
@hidro как создавать файлы cookie? - person Michael A; 02.03.2016
comment
Используете Cookie.Builder? https://github.com/square/okhttp/blob/master/okhttp/src/main/java/okhttp3/Cookie.java#L451 - person hidro; 02.03.2016
comment
Добавление кодов ниже мне помогло. Спасибо! CookieManager cookieManager = новый CookieManager (); cookieManager.setCookiePolicy (CookiePolicy.ACCEPT_ALL); OkHttpClient client = новый OkHttpClient.Builder () .cookieJar (новый JavaNetCookieJar (cookieManager)) .build (); - person Can Uludağ; 06.04.2016
comment
К вашему сведению: в ближайшем будущем они планируют удалить модуль okhttp-urlconnection. https://github.com/square/okhttp/blob/master/CHANGELOG.md - person Tobliug; 12.04.2016
comment
Использование только HttpUrl ограничивает cookie только этим URL-адресом - и на самом деле это не особенно полезно. Это должно быть просто доменное имя в качестве ключа - и тогда все будет работать так, как задумано. - person slott; 26.04.2016
comment
Это не правильно. saveFromResponse заменяет список, а не объединяет их. Это означает, что установка любого файла cookie стирает все файлы cookie, установленные в предыдущих запросах. - person Agent_L; 30.11.2016
comment
Я согласен с @Agent_L. Это заменяет все файлы cookie каждый раз, когда поступают новые файлы cookie. Это означает, что если вы войдете в систему, получите в ответ файл cookie аутентификации, а затем сделаете другой запрос, который возвращает другой файл cookie в ответе, cookie аутентификации будет перезаписан, и вы больше не войдете в систему. - person Cypress Frankenfeld; 26.06.2017
comment
@Agent_L и как мне слить куки? - person Maxim Toyberman; 04.07.2018
comment
@MaximToyberman Вы бы хотели что-то похожее на это private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>(); @Override public void saveFromResponse(HttpUrl url, List<Cookie> cookies) { if(cookieStore.containsKey(url.host())) { cookieStore.get(url.host()).addAll(cookies); } else { cookieStore.put(url.host(), cookies); } } - person Mikael Mengistu; 27.09.2018
comment
По-прежнему не могу получить ответ. На сервере отображается некоторая проблема с сеансом, но поскольку он работает в Интернете и iOS, у меня нет другого варианта, просто проверить свой код. - person Priyanka Singhal; 15.03.2019
comment
Не могу понять, почему сеанс не работал с реализацией CookieJar. CookieManager работает как шарм. - person Kimi Chiu; 30.06.2020

Pre OkHttp 3, вы можете передать CookieHandler своему экземпляру OkHttpClient. Вы можете использовать реализацию CookieManager из java.net или реализовать свою собственную, если хотите. Выберите политику, которая лучше всего соответствует вашим потребностям.

OkHttpClient client = new OkHttpClient();
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
client.setCookieHandler(cookieManager);

OkHttp будет сохранять файлы cookie, полученные от Responses, в CookieHandler и читать из него при отправке запросов. Это будет сделано для сопоставления URI запроса / ответа.

person Miguel    schedule 17.06.2014
comment
Важное примечание: CookieManager не является постоянным. В следующий раз, когда вы запустите приложение, банка cookie будет пуста. - person Jesse Wilson; 18.06.2014
comment
@JesseWilson, как же сделать его постоянным? - person Saeed Neamati; 06.08.2015
comment
Постоянные файлы cookie еще не реализованы. Если они вам нужны, вам нужно создать свой собственный CookieStore. - person Jesse Wilson; 07.08.2015
comment
@JesseWilson Вы правы. Вот библиотека, которая помогает сохранить CoockieJar github.com/franmontiel/PersistentCookieJar - person Manjunath; 09.08.2016
comment
Метод setCookieHandler отсутствует okhttp 3.0 - person Asthme; 23.12.2016
comment
Нужно ли нам внедрять новый CookieJar () в каждый запрос okhttp, или мы можем сделать это раз и навсегда? - person Miljan Rakita; 11.11.2017

Мне нужно было поделиться файлом Cookie Jar по умолчанию (CookieManager.getInstance ()), так что, похоже, для меня это сработало.

return new CookieJar() {

        @Override
        public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
            CookieManager cookieManager = CookieManager.getInstance();

            for (Cookie cookie : cookies) {
                cookieManager.setCookie(url.toString(), cookie.toString());
            }
        }

        @Override
        public List<Cookie> loadForRequest(HttpUrl url) {
            CookieManager cookieManager = CookieManager.getInstance();
            List<Cookie> cookies = new ArrayList<>();
            if (cookieManager.getCookie(url.toString()) != null) {
                String[] splitCookies = cookieManager.getCookie(url.toString()).split("[,;]");
                for (int i=0; i<splitCookies.length; i++) {
                    cookies.add(Cookie.parse(url, splitCookies[i].trim()));
                }
            }
            return cookies;
        }
    };
person hmac    schedule 14.06.2017
comment
Спасибо. Работает отлично. Прекрасная работа. Простое решение, спасибо !! - person KZoNE; 17.08.2017
comment
hii @hmac, этот подход у меня работает. Можете ли вы рассказать мне, как очистить cookie при выходе пользователя из системы? - person Rozina; 24.05.2018
comment
Решил проблему очистки куки. Вот ссылка может помочь кому-то stackoverflow.com/a/50505170/8159810 - person Rozina; 24.05.2018