新增額外的 HTTP 要求標頭

帕沃爾.德羅塔 (Pavol Drotar)
Pavol Drotar

HTTP 要求包含「User-Agent」或「Content-Type」等標頭。除了瀏覽器附加的標頭外,Android 應用程式也可以透過 EXTRA_HEADERS 意圖額外項目新增 Cookie 或參照網址等額外標頭。基於安全考量,Chrome 會根據意圖的啟動方式和位置篩選部分額外標頭。

「跨來源」要求需要多一層安全保護,因為用戶端和伺服器不屬於同一方。本指南將說明如何透過 Chrome 的自訂分頁啟動這類要求,例如透過瀏覽器分頁開啟網址的應用程式啟動的意圖。在 Chrome 83 版之前,開發人員可在啟動「Custom 分頁」時新增任何標頭。自 83 版起,Chrome 開始篩選全部內容 (已核准的跨來源標頭除外),因為未經許可的標頭會帶來安全性風險。從 Chrome 86 版開始,當伺服器和用戶端使用數位資產連結與跨來源要求連結時,可以將未核准的標頭附加到跨來源要求。此行為的摘要如下表所示:

Chrome 版本 允許使用 CORS 標頭
Chrome 83 以下版本 已核准,未列入核准清單
Chrome 83 到 Chrome 85 已列入核准清單
從 Chrome 第 86 版開始 已列入核准清單,且在設定數位資產連結時未獲準

表 1.:篩選未許可的 CORS 標頭。

本文說明如何在伺服器和用戶端之間設定已驗證連線,並使用該連線傳送核准清單以及未列入核准清單的 HTTP 標頭。您可以跳到程式碼的「在自訂分頁意圖中加入額外標頭」。

背景

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

跨源資源共享 (CORS) 可讓來自一個來源的網頁應用程式要求不同來源的資源。CORS-approvelisted 標頭清單則會在 HTML 標準中保留。核准名單標頭範例如下表所示:

標題 說明
接受語言 宣傳客戶能理解的自然語言
內容語言 說明目標對象的語言。
內容類型 代表資源所用的媒體類型

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

系統會將核准的標頭視為安全,因為這些標頭不包含敏感的使用者資訊,也不太可能導致伺服器執行可能有害的作業。

未獲得核准的標頭範例如下表所示:

標題 說明
不記名符記 在伺服器上驗證用戶端
來源 會指出要求來源
餅乾 包含伺服器設定的 Cookie

表 3.:未許可的 CORS 標頭範例。

HTML 標準和伺服器假設跨來源要求僅包含核准清單中的標頭,不建議您在 CORS 要求中附加未核准的標頭。從跨來源網域傳送未經核准的標頭,可能會讓惡意第三方應用程式使用 Chrome (或其他瀏覽器) 儲存及附加至要求的使用者 Cookie 建立標頭。Cookie 可以驗證 無法實現的惡意伺服器交易

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

自訂分頁是一種特殊的操作方式,能在自訂的瀏覽器分頁中啟動網頁。您可以使用 CustomTabsIntent.Builder() 建立自訂分頁意圖。您也可以使用具有 Browser.EXTRA_HEADERS 旗標Bundle,將標頭附加至這些意圖:

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

自訂分頁連線是用來設定應用程式和 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 也會篩選這類標頭。只有相同來源的用戶端和伺服器才能附加檔案,並透過數位資產連結進行驗證。