Что такое headers в HTTP
Что проверяют
Понимаете ли вы, что заголовки это управляющий канал протокола, а не приложение к телу запроса. Для мобильной разработки важна прикладная сторона: авторизация, кэш, сжатие и версия API живут именно в заголовках, и сетевой клиент настраивается через них.
Как отвечать
Заголовок это пара имени и значения, передаваемая в запросе и в ответе. Имена регистронезависимы, одно имя может повторяться, а в HTTP/2 и HTTP/3 заголовки идут сжатыми в двоичном виде, плюс появляются служебные поля метода и пути. Смысл групп: описание тела (Content-Type, Content-Length, Content-Encoding), согласование (Accept, Accept-Language), доступ (Authorization, Cookie), кэширование (Cache-Control, ETag, If-None-Match).
В Android разговор сразу уходит в перехватчики OkHttp:
val client = OkHttpClient.Builder()
.addInterceptor { chain ->
val request = chain.request().newBuilder()
.header("Authorization", "Bearer $token")
.build()
chain.proceed(request)
}
.build()Полезно добавить: обновление протухшего токена делают через Authenticator, а не в перехватчике; кэш клиента живёт по Cache-Control и ETag, условный запрос возвращает ответ без тела; сжатие клиент запрашивает и распаковывает сам, пока вы не выставили заголовок кодирования вручную.
Где спотыкаются
Логируют заголовки целиком. Перехватчик логирования на полном уровне в релизной сборке отправляет токены в системный лог и в отчёты о сбоях. Секретные заголовки скрывают штатным механизмом, а уровень логов делают зависимым от типа сборки.
Считают, что имя встречается один раз. Берут первое значение и теряют остальные куки или несколько значений в поле согласования. Читать такие заголовки нужно списком, а не единственным значением.
Ломают кэширование руками. Ставят свой заголовок кодирования и получают сырой сжатый поток в теле, либо отключают серверный кэш и заставляют приложение качать одно и то же по сотовой сети. Отдельная ошибка это перенести токен в параметры адреса, откуда он попадает в логи прокси и в историю переходов.