Android. Принять себя или Cookie?

Android. Принять себя или Cookie?

Android. Принять себя или Cookie?

Печенья, кеки, кукисы, ку-ку, кексы… нет, куки!Cookie — это что?

Почему их не нужно принимать?

Безопасно ли это?

CookieJar, CookieManager, CookieStore… WebView?

А также истории про то, как жить с cookie в большом приложении, и сколько эмоций вы испытаете, если в вашем приложении есть WebView.

За техническую консультацию (и моральную поддержку при работе с cookie на Android) спасибо Сергею Мазулеву и Максиму Шестоперову, команда OzonID.

За консультацию по юридическим вопросам спасибо Михаилу Ратушному, руководителю практики защиты персональных данных Ozon.

Cookie — они зачем?
Сначала определим, из чего состоят cookie и для чего используются. В общем смысле, не только на Android.

В большинстве случаев их удобно использовать для передачи:

токенов авторизации;

флагов с бэка на мобилку;

параметров устройства с мобилки на бэк.

Но зашить можно любую информацию, ограничений нет. Например, можно удобно организовать авторизацию:

1. пользователь вводит логин и пароль;

2. бэкенд авторизует юзера и присылает в ответ cookie-токен;

3. клиент начинает отсылать в cookie-токен на все следующие запросы.

Готово, бэкенд знает, от какого пользователя летят запросы.

Как выглядят cookie?
Cookie — это строка, состоящая из:

ключа;

значения;

атрибутов.

Ключ и значение могут быть произвольные. Атрибуты заранее определены, но при этом все они опциональны — можно присылать только нужные.

Например,

Cookie передаются как один из header (заголовков) http(s)-запроса. Причем как с клиента на бэкенд, так и в обратную сторону.

Cookie == Header?
Да, cookie передаётся в списке хедеров, как и все остальные хедеры (например, user-agent).

Но есть отличие: cookie автоматически прикрепляются к домену (см. атрибут domain) и начинают отсылаться в каждом запросе на этот domain (хост).

Например, с домена ozon.ru бэк прислал cookie userId = 123. Это значит, что в следующий запрос на ozon.ru автоматически добавится header с этой же cookie userId = 123. И она будет улетать, пока не протухнет (см. Session vs Permanent Cookie) или не будет перезаписана устройством или новой cookie userId = 456 с бэкенда.

Будьте осторожны со значениями — если положить строку, содержащую символ точки с запятой «;» или запятой «,», некоторые клиенты могут неправильно распарсить cookie.

Почему приложения не спрашивают у нас разрешения?
Уверен, где-нибудь в интернете есть коллекция всех вариаций запроса на работу с cookie на web-сайтах…

Но почему подобный запрос не вылазит в каждом приложении?

Важно: не является истиной в последней инстанции. Если вы Большая компания — проконсультируйтесь с юристом 😉

Важноx2: речь идет про РФ. В вашей местности всё может быть совсем по-другому 😉

Общее правило:

явно запрашивать у пользователя разрешение на передачу cookie нужно, если они не являются технически необходимыми для работы приложения.

Например, запрашивать разрешение

не нужно: в cookie передаются токены авторизации пользователя, которые используются только внутри компании;

нужно: в cookie передаются рекламные идентификаторы, передаваемые другим компаниям.

Где почитать подробнее:

РФ — Федеральный закон № 152-ФЗ «О персональных данных»

GDPR

ePrivacy Directive

В приложении Ozon мы не запрашиваем разрешение на cookie. А на сайте даём пользователю выбор:

Как передаются Cookie
Cookie передаются в хедерах http-запросов в обе стороны: от бэка на мобилку и с мобилки на бэк.

бэк присылает cookie в заголовке с name = Set Cookie, они прикрепляются к domain;

Android-приложение при формировании запроса на domain находит прикрепленные к нему cookie и отсылает их в заголовке name = Cookie.

Также создать cookie и прикрепить их к domain можно локально через CookieManager.put(…). Но в этом случае необходимо самостоятельно следить за их жизненным циклом, не перепутать домены и не забыть про атрибуты.

В каждом запросе (и ответе) может быть несколько заголовков Cookie (Set Cookie).

Session vs Permanent Cookie
Permanent — если передать атрибут expiresIn (max-age), то cookie будут жить в памяти, пока не протухнут;

Session — если не передавать атрибут expiresIn (max-age), то cookie будут жить в памяти, пока не прервётся соединение (например, не будет перезагружено приложение).

Это описание стандартного поведения. Его, например, реализует CookieHandler.getDefault() (что это за класс — рассмотрим ниже).

Вам, конечно, никто не помешает сохранить cookie в ПЗУ навсегда или стереть их в любой момент.

Безопасность
К cookie стоит относиться так же, как и к обычным https-запросам.

С одной стороны, это всё шифруется вместе с телом запроса, но с другой, — кому надо, тот найдет способ перехватить.

Поэтому передаём минимум чувствительной информации (пароли в открытом виде не стоит).

Как работать с cookie в Android
Нам потребуется несколько классов из стандартных библиотек:

OkHttpClient — базовый класс, настраивающий все взаимодействие с сетью;

CookieJar — DAO для работы с CookieManager;

CookieManager — DAO для работы с CookieStore;

CookieStore — хранилище кук.

Собрав цепочку из них, мы организуем хранение, управление и передачу cookie.

При этом многие из этих классов имеют стандартные реализации, переопределять которые стоит только при необходимости.

Запись опубликована в рубрике Интересные статьи. Добавьте в закладки постоянную ссылку.