[Перевод] Пара HTTP-заголовков, о которых, похоже, не знают разработчики

Вот какое дело: как показывают мои изыскания, большинство веб-разработчиков поразительно мало знают об HTTP-заголовках или, в целом, о стандарте HTTP. Я имею в виду, что я понимаю то, что во многих университетах и школах, вероятно, этому не учат (там, где я учился, определённо, так и было). А кто будет, сидя дома праздным воскресным утром, думать о том, чтобы развлечь себя чтением стандарта HTTP? Да никто. Знаю, но… есть одно важное обстоятельство: отсутствие хоть какого-то понимания стандарта HTTP — это зияющая дыра в знаниях веб-разработчиков, в знаниях многих из тех, кто это читает. Предлагаю это исправить.

e181c95dd286a21c02c5f4f75f261bd5.png

Что представляют собой HTTP-заголовки

HTTP-заголовки предназначены для организации обмена метаданными о запросах и ответах между клиентами и серверами.

Клиент и сервер передают друг другу в заголовках дополнительную информацию. Заголовки имеются и в запросах, и в ответах.

Клиент (браузер, команда curl и так далее) может отправить серверу заголовок Accept: text/html для того чтобы указать на то, что ему хотелось бы, чтобы запрос оформлялся бы в виде HTML-документа. Или заголовок может быть таким:  Accept: /. Тем самым клиент сообщит серверу о том, что сервер может отправить ему всё что угодно, так как клиент способен разобраться с любыми данными, которые получит от сервера.

Сервер может отправить клиенту ответ с заголовком Cache-Control: public, max-age=600. Фрагмент public этого заголовка указывает на то, что возвращённый документ может быть кеширован в любом кеше. Ответ сервера не предназначен лишь для одного конкретного пользователя. А фрагмент max-age=600 говорит о том, что через 600 секунд материал необходимо из кеша удалить.

В результате мы можем сказать, что HTTP-заголовки состоят из двух частей, разделённых двоеточием. Это — имя заголовка, за которым следует значение. Имена заголовков нечувствительны к регистру.

Изучение существующих заголовков

Лучший способ изучения HTTP-заголовков, у которых уже имеются определённые имена, которым уже назначены роли в клиент-серверном взаимодействии, заключается в посещении соответствующего раздела сайта MDN.

Дело в том, что сервер и клиент могут договориться об использовании любого количества HTTP-заголовков, имеющих произвольные имена и значения. Но я полагаю, что нет смысла в изобретении новых HTTP-заголовков для своего приложения до проверки официального списка существующих заголовков. Высока вероятность того, что кому-то уже был нужен заголовок для решения точно такой же задачи, которую нужно решить «изобретателю».

Главная причина, по которой нежелательно «изобретать колесо» в сфере HTTP-заголовков, используемых неким приложением, заключается в том, чтобы не усложнять жизнь пользователям этого приложения. Есть и ещё одна причина — к существующим HTTP-заголовкам уже имеется документация.

Я сейчас работаю над приложением, которому нужно обращаться к множеству различных API. И я могу сказать, что я возблагодарил бы судьбу, если бы все разработчики всех приложений могли бы в один прекрасный день начать пользоваться одними и теми же заголовками. Многие из этих API придерживаются стандартов. На самом деле — большая их часть. Их, определённо, больше 50%. Но, по моим скромным оценкам, около 30% API стандартов не придерживается. Один из трёх API, который я интегрировал в свой проект, вынуждает меня использовать заголовки, созданные специально для него его разработчиками, а документация подобных API никогда в полной мере не объясняет особенности поведения таких заголовков.

Необоснованно сложным оказывается написание кода обработки заголовков для API, когда для работы с разными API требуется отправлять одну и ту же информацию, оформленную множеством различных способов. Особенно — если все эти «различные способы» как следует не документированы. А дело тут в том, что, будем откровенны, документацию мы писать не умеем. Поэтому предлагаю сделать жизнь пользователей наших систем чуть лучше и просто использовать заголовки, которые уже хорошо документированы.

Первый HTTP-заголовок, о котором знает слишком мало разработчиков: Authorization

Не знаю, как ещё это выразить, но… заголовок Authorization предназначен для авторизации. Знаю — это шокирующая правда. А если серьёзно, то, если вы ожидаете запросов к серверу, в которых клиент должен отправлять какую-то аутентификационную информацию, вроде ключей API, то, пожалуйста, используйте этот заголовок. Давайте просто все решим, что с этого момента мы будем помещать данные для авторизации во всех API в заголовок Authorization. Это позволит нам сделать нашу жизнь намного проще.

Давайте не будем изобретать собственные заголовки вроде PRIVATE-TOKEN, или DD-API-KEY, или X-SF-Token и не будем запихивать токены авторизации в параметры GET или POST. Давайте просто остановимся на заголовке Authorization. Пользоваться им очень просто. Данные в нём передаются так:

Authorization:  

Так как существует множество способов аутентификации на сервере, заголовок Authorization поддерживает несколько стандартных типов аутентификации. Именно по этой причине тут имеется фрагмент . Самыми распространёнными типами аутентификации являются Basic и Bearer. Последний используется для OAuth2.

Фрагмент authorisation-parameters — это конкретные данные, имеющие отношение к авторизации (имя пользователя и пароль, токены и так далее), закодированные в соответствии с правилами выбранного типа авторизации.

Второй HTTP-заголовок, о котором знает слишком мало разработчиков: Retry-After

Когда вы реализуете в своём API систему ограничения частоты запросов, используйте этот заголовок для того чтобы сообщить вызывающей стороне о том, сколько времени она должна ждать прежде чем делать новый запрос к вашему API.

Вообще — заголовок Retry-After был спроектирован для использования в следующих ответах:

  • 503 — Service Unavailable.

  • 429 — Too Many Requests. Этот код ответа используется для ограничения частоты запросов.

  • Очень редко им пользуются в ответе с кодом 301 — Moved Permanently.

В этом заголовке сервер должен вернуть либо целое число, представляющее количество секунд, которое должно пройти перед повторным выполнением запроса, либо значение, содержащее дату и время, после наступления которых можно выполнить повторный запрос.

Retry-After: 
Retry-After: 

Всё это значит, что для решения подобных задач не нужно изобретать собственные заголовки, которые могут называться X-Rate-Limit-Remaining-Seconds или X-RateLimit-Reset. Ведь тот, кому это нужно, всегда может воспользоваться заголовком Retry-After.

Итоги

Итак, теперь вы кое-что знаете об HTTP-заголовках, и о том, как с ними разумнее всего обращаться. А теперь расскажите об этом другим. И, пожалуйста, пользуйтесь описанными тут двумя заголовками для решения задач авторизации и ограничения частоты запросов к серверу, вместо того, чтобы изобретать что-то своё.

О, а приходите к нам работать?

© Habrahabr.ru