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