HTTP リクエスト ヘッダーを追加する

HTTP リクエストには、User-Agent や Content-Type などのヘッダーが含まれています。Android アプリでは、ブラウザが添付するヘッダーのほかに、EXTRA_HEADERS インテント エクストラを使用して、Cookie やリファラーなどのヘッダーを追加できます。セキュリティ上の理由から、Chrome はインテントの起動方法と場所に応じて一部の追加ヘッダーをフィルタリングします。

クロスオリジン リクエストでは、クライアントとサーバーが同じ当事者によって所有されていないため、追加のセキュリティ レイヤが必要です。このガイドでは、そのようなリクエストを Chrome のカスタムタブ(ブラウザタブで URL を開くアプリから起動されるインテント)を介して起動する方法について説明します。Chrome 83 までは、カスタムタブの起動時に任意のヘッダーを追加できました。バージョン 83 以降では、承認されていないヘッダーがセキュリティ上のリスクをもたらすため、承認リストに登録されたクロスオリジン ヘッダーを除くすべてのクロスオリジン ヘッダーのフィルタリングが開始されました。Chrome 86 以降では、サーバーとクライアントがデジタル アセット リンクを使用して関連付けられている場合に、承認されていないヘッダーをクロスオリジン リクエストに追加できます。この動作を次の表にまとめます。

Chrome のバージョン 許可される CORS ヘッダー
Chrome 83 より前 承認済み、非承認登録済み
Chrome 83 ~ Chrome 85 承認済みリスト済み
Chrome 86 以降 デジタル アセット リンクが設定されている場合は、承認済みリスト済み、非承認リスト登録済み

表 1.:承認されていない CORS ヘッダーのフィルタリング。

この記事では、サーバーとクライアントの間に確認済みの接続を設定し、それを使用して、承認リストに登録されている HTTP ヘッダーと不承認リストの http ヘッダーを送信する方法について説明します。コードについては、カスタムタブ インテントにヘッダーを追加するに進んでください。

背景

承認済みリストと非承認リストの CORS リクエスト ヘッダー

クロスオリジン リソース シェアリング(CORS)を使用すると、あるオリジンのウェブ アプリケーションが別のオリジンのリソースをリクエストできます。CORS-approve lists ヘッダーのリストは、HTML 標準で管理されています。次の表に、承認リストに登録されているヘッダーの例を示します。

ヘッダー Description
承認する言語 クライアントが理解できる自然言語をアドバタイズする
コンテンツの言語 現在のオーディエンスが想定する言葉遣いを説明
コンテンツ タイプ リソースのメディアタイプを示します。

表 2.:承認リストの CORS ヘッダーの例。

承認リストに登録されたヘッダーは、ユーザーの機密情報を含んでおらず、サーバーが損害を与える可能性のあるオペレーションを行う可能性が低いため、安全とみなされます。

次の表に、承認されていないヘッダーの例を示します。

ヘッダー Description
署名なしトークン サーバーでクライアントを認証する
オリジン リクエストの送信元を示す
Cookie サーバーによって設定された 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 リクエストにいつでも添付できます。不承認となっているヘッダーはデフォルトで フィルタされます他のブラウザでは動作が異なる場合がありますが、不承認リストのヘッダは一般的にブロックされると考えられます。

未承認のヘッダーをカスタムタブに含めるには、まずデジタル アクセス リンクを使用してクロスオリジン接続を確認します。次のセクションでは、これらのカスタムタブ インテントをセットアップし、必要なヘッダーを指定してカスタムタブ インテントを起動する方法を説明します。

カスタムタブ インテントにヘッダーを追加する

承認されていないヘッダーをカスタムタブ インテントで渡すには、Android とウェブアプリの間にデジタル アセット リンクを設定し、作成者が両方のアプリケーションを所有していることを確認する必要があります。

公式ガイドに沿って、デジタル アセット リンクを設定します。リンク関係には「delegate_permission/common.use_as_origin」を使用します。これは、リンクが検証されると、両方のアプリが同じオリジンに属することを示します。

追加のヘッダーを使用してカスタムタブ インテントを作成する

Custom Tabs インテントを作成するには、複数の方法があります。androidX で利用可能なビルダーを使用するには、このライブラリをビルド依存関係に追加します。

MULTI_LINE_CODE_PLACEHOLDER_1

インテントをビルドして、ヘッダーを追加します。

MULTI_LINE_CODE_PLACEHOLDER_2

カスタムタブ接続は、アプリと Chrome タブの間に CustomTabsSession を設定するために使用されます。アプリとウェブアプリが同じオリジンに属していることを確認するには、セッションが必要です。デジタル アセット リンクが正しく設定されている場合にのみ、この検証に合格します。

CustomTabsClient.warmup() を呼び出すことをおすすめします。これにより、ブラウザ アプリをバックグラウンドで事前に初期化でき、URL を開くプロセスを高速化できます。

MULTI_LINE_CODE_PLACEHOLDER_3

検証後にインテントを起動するコールバックをセットアップする

CustomTabsCallback がセッションに渡されました。オリジンの確認が成功したら、以前に作成した CustomTabsIntent を起動するように onRelationshipValidationResult() をセットアップしました。

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 はデフォルトでそれらをフィルタします。接続は、デジタル アセット リンクによって検証され、同じオリジンのクライアントとサーバーに対してのみ許可されます。