Добавьте дополнительные заголовки HTTP-запросов

HTTP-запросы содержат такие заголовки, как User-Agent или Content-Type. Помимо заголовков, прикрепленных браузерами, приложения Android могут добавлять дополнительные заголовки, такие как Cookie или Referrer, посредством дополнительного намерения EXTRA_HEADERS . По соображениям безопасности Chrome фильтрует некоторые дополнительные заголовки в зависимости от того, как и где запускается намерение.

Запросы между источниками требуют дополнительного уровня безопасности, поскольку клиент и сервер не принадлежат одной и той же стороне. В этом руководстве обсуждается запуск таких запросов через пользовательские вкладки Chrome, то есть намерения, запускаемые из приложений, которые открывают URL-адрес на вкладке браузера. До версии Chrome 83 разработчики могли добавлять любые заголовки при запуске пользовательской вкладки. Начиная с версии 83, Chrome начал фильтровать все, кроме утвержденных заголовков перекрестного происхождения, поскольку неутвержденные заголовки представляли угрозу безопасности. Начиная с Chrome 86, можно прикреплять неутвержденные заголовки к запросам между источниками, когда сервер и клиент связаны с помощью ссылки на цифровой актив . Это поведение обобщено в следующей таблице:

Хром-версия Заголовки CORS разрешены
до Chrome 83 одобренный, неутвержденный
от Chrome 83 до Chrome 85 одобренный список
начиная с Chrome 86 и далее утвержденный список, не одобренный, если установлена ​​ссылка на цифровой актив

Таблица 1. Фильтрация неутвержденных заголовков CORS.

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

Фон

Утвержденные и неутвержденные заголовки запросов CORS

Совместное использование ресурсов между источниками (CORS) позволяет веб-приложению из одного источника запрашивать ресурсы из другого источника. Список заголовков , одобренных CORS, поддерживается в стандарте HTML . Примеры утвержденных заголовков показаны в следующей таблице:

Заголовок Описание
принять-язык рекламирует естественные языки, которые понимает клиент
язык контента описывает язык, предназначенный для текущей аудитории
Тип содержимого указывает тип носителя ресурса

Таблица 2. Пример заголовков CORS, включенных в утвержденный список.

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

Примеры неутвержденных заголовков показаны в следующей таблице:

Заголовок Описание
жетон на предъявителя аутентифицирует клиента на сервере
источник указывает происхождение запроса
печенье содержит файлы cookie, установленные сервером

Таблица 3. Пример неутвержденных заголовков CORS.

Прикрепление неутвержденных заголовков к запросам CORS не рекомендуется стандартом HTML, и серверы предполагают, что запросы из разных источников содержат только утвержденные заголовки. Отправка неутвержденных заголовков из доменов с перекрестным происхождением позволит вредоносным сторонним приложениям создавать заголовки, которые неправильно используют пользовательские файлы cookie, которые Chrome (или другой браузер) хранит и прикрепляет к запросам. Файлы cookie могут аутентифицировать вредоносные транзакции сервера, которые в противном случае были бы невозможны.

Прикрепление заголовков, утвержденных CORS, к запросам настраиваемых вкладок

Пользовательские вкладки — это особый способ запуска веб-страниц на настраиваемой вкладке браузера. Намерения пользовательских вкладок можно создать с помощью CustomTabsIntent.Builder() . Вы также можете прикрепить заголовки к этим намерениям, используя Bundle с флагом Browser.EXTRA_HEADERS :

CustomTabsIntent intent = new CustomTabsIntent.Builder(session).build();

Bundle headers = new Bundle();
headers.putString("bearer-token", "Some token");
headers.putString("redirect-url", "Some redirect url");   
intent.intent.putExtra(Browser.EXTRA_HEADERS, headers);

intent.launchUrl(Activity.this, Uri.parse("http://www.google.com"));

Мы всегда можем прикрепить утвержденные заголовки к запросам CORS настраиваемых вкладок. Однако Chrome по умолчанию фильтрует неутвержденные заголовки. Хотя поведение других браузеров может отличаться, разработчикам следует ожидать, что неутвержденные заголовки в целом будут блокироваться.

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

Добавление дополнительных заголовков в пользовательские вкладки

Чтобы разрешить передачу неутвержденных заголовков через намерения пользовательской вкладки, необходимо настроить ссылку на цифровой ресурс между Android и веб-приложением, которая проверяет, что автор владеет обоими приложениями.

Следуйте официальному руководству , чтобы настроить ссылку на цифровой актив. Для отношения ссылки используйте «delegate_permission/common.use_as_origin», который указывает, что оба приложения принадлежат к одному и тому же источнику после проверки ссылки.

Создайте пользовательскую вкладку с дополнительными заголовками

Существует несколько способов создания намерения «Пользовательские вкладки» . Вы можете использовать сборщик, доступный в androidX, добавив библиотеку в зависимости сборки:

MULTI_LINE_CODE_PLACEHOLDER_1

Создайте намерение и добавьте дополнительные заголовки:

MULTI_LINE_CODE_PLACEHOLDER_2

Соединение «Пользовательские вкладки» используется для настройки сеанса CustomTabsSession между приложением и вкладкой Chrome. Нам нужен сеанс, чтобы убедиться, что приложение и веб-приложение принадлежат одному и тому же источнику. Проверка проходит только в том случае, если ссылки на цифровые активы настроены правильно.

Рекомендуется вызвать CustomTabsClient.warmup() . Это позволяет приложению браузера выполнить предварительную инициализацию в фоновом режиме и ускорить процесс открытия URL-адреса.

MULTI_LINE_CODE_PLACEHOLDER_3

Настройте обратный вызов, который запускает намерение после проверки.

CustomTabsCallback был передан в сеанс. Мы настроили его onRelationshipValidationResult() для запуска ранее созданного CustomTabsIntent после успешной проверки источника.

MULTI_LINE_CODE_PLACEHOLDER_4

Привязка подключения к службе пользовательских вкладок

Привязка службы запускает службу, и в конечном итоге будет вызван метод onCustomTabsServiceConnected() соединения. Не забудьте соответствующим образом отвязать службу. Привязка и отвязка обычно выполняются в методах жизненного цикла активности onStart() и onStop() .

// Bind the custom tabs service connection.
// Call this in onStart()
CustomTabsClient.bindCustomTabsService(this,
    CustomTabsClient.getPackageName(MainActivity.this, null), connection);

// …
// Unbind the custom tabs service.
// Call this in onStop().
unbindService(connection);

Код демо-приложения

Более подробную информацию о службе пользовательских вкладок можно найти здесь . Рабочий пример приложения см. в репозитории android-browser-helper на GitHub.

Краткое содержание

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