新增額外的 HTTP 要求標頭

Pavol Drotar
Pavol Drotar

HTTP 要求包含 User-Agent 或 Content-Type 等標頭。除了瀏覽器附加的標頭外,Android 應用程式可能會透過 EXTRA_HEADERS Intent extra 新增額外的 Cookie 或 Referrer 標頭。為了安全起見,Chrome 會根據意圖啟動的方式和位置,篩選部分額外的標頭。

由於用戶端和伺服器並非由同一方擁有,因此跨來源要求需要額外的安全層。本指南將說明如何透過 Chrome 自訂分頁啟動這類要求,也就是在瀏覽器分頁中開啟網址的應用程式所啟動的意圖。在 Chrome 83 之前,開發人員可以在啟動自訂分頁時新增任何標頭。自第 83 版起,Chrome 開始篩除所有非已核准列表的跨來源標頭,因為非核准列表的標頭會造成安全性風險。自 Chrome 86 起,如果伺服器和用戶端使用數位資產連結建立關聯,則可將未列入核准清單的標頭附加至跨來源要求。下表摘要說明這項行為:

Chrome 版本 允許的 CORS 標頭
在 Chrome 83 之前 已核准、未核准
Chrome 83 到 Chrome 85 approvelisted
適用於 Chrome 86 以上版本 已核准列入、未核准列入 (在設定數位資產連結時)

表 1:篩選未列入許可清單的 CORS 標頭。

本文將說明如何在伺服器和用戶端之間建立已驗證的連線,並使用該連線傳送已核准清單和非核准清單 HTTP 標頭。您可以略過新增額外標頭至自訂分頁意圖,直接查看程式碼。

背景

核准清單與未列入核准的 CORS 要求標頭

跨來源資源共享 (CORS) 可讓來自某個來源的網路應用程式要求不同來源的資源。CORS 核准清單的標頭清單由 HTML 標準維護。已加入許可清單的標頭範例如下表所示:

標題 說明
accept-language 宣傳客戶可瞭解的自然語言
content-language 說明目前目標對象的語言
內容類型 表示資源的媒體類型

表 2:已核准的 CORS 標頭範例。

已核准的標頭會被視為安全,因為這些標頭不含機密使用者資���,且不太可能導致伺服器執行可能造成損害的作業。

下表列出非核准清單標頭的範例:

標題 說明
bearer-token 在伺服器上驗證用戶端
起源 表示要求來源
餅乾 包含由伺服器設定的 Cookie

表 3:範例:未列入核准清單的 CORS 標頭。

HTML 標準不建議將未核准的標頭附加至 CORS 要求,且伺服器會假設跨來源要求只包含核准的標頭。如果從跨來源網域傳送未列入核准清單的標頭,惡意第三方應用程式就可能會製作出濫用 Chrome (或其他瀏覽器) 儲存並附加至要求的使用者 Cookie 的標頭。這些 Cookie 可驗證惡意伺服器交易,否則無法驗證。

將 CORS 核准清單標頭附加至自訂分頁要求

自訂分頁是一種特殊方式,可在自訂的瀏覽器分頁中啟動網頁。您可以使用 CustomTabsIntent.Builder() 建立自訂分頁意圖。您也可以使用 BundleBrowser.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 預設會篩除未列入核准清單的標頭。雖然其他瀏覽器的行為可能不同,但開發人員一般認為系統會封鎖未列入許可清單的標頭。

在自訂分頁中加入未列入核准清單的標頭,可透過以下方式進行:先使用數位存取連結驗證跨來源連線。下一節將說明如何設定這些項目,並透過必要的標頭啟動 Custom Tabs 意圖。

在自訂分頁意圖中加入額外標頭

如要允許非核准清單中的標頭透過自訂分頁意圖傳遞,您必須在 Android 和網頁應用程式之間設定數位資產連結,驗證作者是否擁有這兩個應用程式。

請按照官方指南設定數位資產連結。如果是連結關係,請使用「Delegate_permission/common.use_as_origin」",代表連結通過驗證後,兩個應用程式都屬於同一個來源。

使用額外標頭建立自訂分頁意圖

您可以透過多種方式建立 Custom Tabs 意圖。您可以將程式庫新增至建構依附元件,以便使用 AndroidX 提供的建構工具:

MULTI_LINE_CODE_PLACEHOLDER_1

建構意圖並新增額外標頭:

MULTI_LINE_CODE_PLACEHOLDER_2

自訂分頁連線是用來設定應用程式和 Chrome 分頁之間的 CustomTabsSession。我們需要使用工作階段,驗證應用程式和網頁應用程式屬於同一個來源。只有在數位資產連結設定正確無誤的情況下,驗證才會通過。

建議您呼叫 CustomTabsClient.warmup()。可讓瀏覽器應用程式在背景預先初始化,並加快網址開啟程序。

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 會根據預設篩除這些標頭。只有透過數位資產連結驗證的相同來源用戶端和伺服器才能附加這些憑證。