Permintaan HTTP berisi header seperti User-Agent atau Content-Type. Selain header yang dilampirkan oleh
browser, aplikasi Android dapat menambahkan header tambahan, seperti Cookie atau Perujuk melalui ekstra Intent
EXTRA_HEADERS. Untuk alasan keamanan, Chrome memfilter beberapa header tambahan bergantung pada cara dan tempat peluncuran intent.
Permintaan lintas origin memerlukan lapisan keamanan tambahan karena klien dan server tidak dimiliki oleh pihak yang sama. Panduan ini membahas peluncuran permintaan tersebut melalui tab khusus Chrome, yaitu intent yang diluncurkan dari aplikasi yang membuka URL di tab browser. Hingga Chrome 83, developer dapat menambahkan header apa pun saat meluncurkan Tab Kustom. Mulai versi 83 dan seterusnya, Chrome mulai memfilter semua header lintas origin kecuali yang terdaftar dalam daftar yang disetujui, karena header yang tidak terdaftar dalam daftar yang disetujui menimbulkan risiko keamanan. Mulai Chrome 86, header yang tidak ada dalam daftar yang disetujui dapat dilampirkan ke permintaan lintas origin, jika server dan klien terkait menggunakan link aset digital. Perilaku ini diringkas dalam tabel berikut:
| Versi Chrome | Header CORS yang diizinkan |
|---|---|
| sebelum Chrome 83 | daftar yang disetujui, daftar yang tidak disetujui |
| Chrome 83 hingga Chrome 85 | telah masuk daftar yang disetujui |
| mulai Chrome 86 | disetujui, tidak disetujui saat penyiapan link aset digital |
Tabel 1.: Pemfilteran header CORS yang tidak ada dalam daftar yang disetujui.
Artikel ini menunjukkan cara menyiapkan koneksi terverifikasi antara server dan klien serta menggunakannya untuk mengirim header http yang masuk dalam daftar yang disetujui dan yang tidak masuk dalam daftar yang disetujui. Anda dapat langsung membuka Menambahkan Header Tambahan ke Intent Tab Kustom untuk melihat kodenya.
Latar belakang
Header Permintaan CORS yang ada dalam daftar yang disetujui vs. Header Permintaan CORS yang tidak ada dalam daftar yang disetujui
Cross-Origin Resource Sharing (CORS) memungkinkan aplikasi web dari satu origin untuk meminta resource dari origin lain. Daftar header CORS-approvelisted dikelola dalam Standar HTML. Contoh header yang masuk daftar yang disetujui ditampilkan dalam tabel berikutnya:
| Header | Deskripsi |
|---|---|
| accept-language | mengiklankan bahasa alami yang dipahami klien |
| content-language | menjelaskan bahasa yang ditujukan untuk audiens saat ini |
| content-type | menunjukkan jenis media resource |
Tabel 2.: Contoh header CORS yang ada dalam daftar yang disetujui.
Header yang masuk dalam daftar yang disetujui dianggap aman karena tidak berisi informasi pengguna yang sensitif dan tidak mungkin menyebabkan server melakukan operasi yang berpotensi merusak.
Contoh header yang tidak masuk dalam daftar yang disetujui ditampilkan dalam tabel berikut:
| Header | Deskripsi |
|---|---|
| bearer-token | mengautentikasi klien di server |
| asal | menunjukkan asal permintaan |
| kue | berisi cookie yang ditetapkan oleh server |
Tabel 3.: Contoh header CORS yang tidak ada dalam daftar yang disetujui.
Melampirkan header yang tidak ada dalam daftar yang disetujui ke permintaan CORS tidak disarankan oleh standar HTML dan server mengasumsikan bahwa permintaan lintas asal hanya berisi header yang ada dalam daftar yang disetujui. Mengirim header yang tidak ada dalam daftar yang disetujui dari domain lintas origin akan memungkinkan aplikasi pihak ketiga yang berbahaya membuat header yang menyalahgunakan cookie pengguna yang disimpan dan dilampirkan Chrome (atau browser lain) ke permintaan. Cookie dapat mengautentikasi transaksi server berbahaya yang seharusnya tidak mungkin dilakukan.
Melampirkan header yang ada dalam daftar yang disetujui CORS ke permintaan Tab Kustom
Tab Kustom adalah cara khusus untuk meluncurkan halaman web di tab browser yang disesuaikan. Intent Tab Kustom
dapat dibuat menggunakan CustomTabsIntent.Builder(). Anda juga dapat melampirkan header ke intent ini menggunakan Bundle dengan flag 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"));
Kita selalu dapat melampirkan header yang ada dalam daftar yang disetujui ke permintaan CORS tab kustom. Namun, Chrome memfilter header yang tidak ada dalam daftar yang disetujui ( ) secara default. Meskipun browser lain mungkin memiliki perilaku yang berbeda, developer harus mengharapkan header yang tidak ada dalam daftar yang disetujui diblokir secara umum.
Cara yang didukung untuk menyertakan header yang tidak ada dalam daftar yang disetujui di tab kustom adalah dengan memverifikasi terlebih dahulu koneksi lintas origin menggunakan link akses digital. Bagian berikutnya menunjukkan cara menyiapkan dan meluncurkan intent Tab Kustom dengan header yang diperlukan.
Menambahkan Header Tambahan ke Maksud Tab Kustom
Menyiapkan link aset digital
Untuk mengizinkan header yang tidak ada dalam daftar yang disetujui diteruskan melalui intent Tab Kustom, Anda harus menyiapkan link aset digital antara aplikasi Android dan web yang memverifikasi bahwa penulis memiliki kedua aplikasi tersebut.
Ikuti panduan resmi untuk menyiapkan link aset digital. Untuk relasi link, gunakan "delegate_permission/common.use_as_origin"` yang menunjukkan bahwa kedua aplikasi berasal dari origin yang sama setelah link diverifikasi.
Membuat Niat Tab Kustom dengan Header Tambahan
Ada beberapa cara untuk membuat intent Tab Kustom. Anda dapat menggunakan builder yang tersedia di androidX dengan menambahkan library ke dependensi build:
implementation 'androidx.browser:browser:1.2.0'
Buat intent dan tambahkan header tambahan:
CustomTabsIntent constructExtraHeadersIntent(CustomTabsSession session) {
CustomTabsIntent intent = new CustomTabsIntent.Builder(session).build();
// Example non-cors-approvelisted headers.
Bundle headers = new Bundle();
headers.putString("bearer-token", "Some token");
headers.putString("redirect-url", "Some redirect url");
intent.intent.putExtra(Browser.EXTRA_HEADERS, headers);
return intent;
}
Menyiapkan Koneksi Tab Kustom untuk Memvalidasi Link Aset
Koneksi Tab Kustom digunakan untuk menyiapkan CustomTabsSession antara aplikasi dan tab Chrome. Kita memerlukan sesi untuk memverifikasi bahwa aplikasi dan aplikasi web berasal dari origin yang sama.
Verifikasi hanya berhasil jika link aset digital disiapkan dengan benar.
Sebaiknya hubungi CustomTabsClient.warmup(). Fitur ini memungkinkan aplikasi browser
melakukan pra-inisialisasi di latar belakang dan mempercepat proses pembukaan URL.
// Set up a connection that warms up and validates a session.
CustomTabsServiceConnection connection = new CustomTabsServiceConnection() {
@Override
public void onCustomTabsServiceConnected(@NonNull ComponentName name,
@NonNull CustomTabsClient client) {
// Create session after service connected.
mSession = client.newSession(callback);
client.warmup(0);
// Validate the session as the same origin to allow cross origin headers.
mSession.validateRelationship(CustomTabsService.RELATION_USE_AS_ORIGIN,
Uri.parse(url), null);
}
@Override
public void onServiceDisconnected(ComponentName componentName) { }
};
Menyiapkan Callback yang Meluncurkan Intent setelah Validasi
CustomTabsCallback diteruskan ke sesi. Kita menyiapkan
onRelationshipValidationResult() untuk meluncurkan CustomTabsIntent yang dibuat sebelumnya
setelah verifikasi asal berhasil.
// Set up a callback that launches the intent after session validated.
CustomTabsCallback callback = new CustomTabsCallback() {
@Override
public void onRelationshipValidationResult(int relation, @NonNull Uri requestedOrigin,
boolean result, @Nullable Bundle extras) {
// Launch custom tabs intent after session was validated as the same origin.
CustomTabsIntent intent = constructExtraHeadersIntent(mSession);
intent.launchUrl(MainActivity.this, Uri.parse(url));
}
};
Mengikat koneksi layanan tab kustom
Mengikat layanan akan meluncurkan layanan dan onCustomTabsServiceConnected() koneksi
akan dipanggil pada akhirnya. Jangan lupa untuk melepaskan layanan dengan benar. Pengikatan dan pelepasan ikatan
biasanya dilakukan dalam metode siklus proses aktivitas onStart() dan 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);
Kode aplikasi demo
Anda dapat menemukan detail selengkapnya tentang Layanan Tab Kustom di sini. Lihat repositori GitHub android-browser-helper untuk mengetahui contoh aplikasi yang berfungsi.
Ringkasan
Panduan ini menunjukkan cara menambahkan header arbitrer ke permintaan CORS tab kustom. Header yang disetujui dapat dilampirkan ke setiap permintaan CORS tab kustom. Header yang tidak ada dalam daftar yang disetujui umumnya dianggap tidak aman dalam permintaan CORS dan Chrome memfilternya secara default. Melampirkannya hanya diizinkan untuk klien dan server dengan origin yang sama, yang diverifikasi oleh link aset digital.