HTTP-verzoeken bevatten headers zoals User-Agent of Content-Type. Naast headers die door browsers worden toegevoegd, kunnen Android-apps extra headers toevoegen, zoals Cookie of Referrer, via de intentie-extra EXTRA_HEADERS. Om veiligheidsredenen filtert Chrome sommige extra headers, afhankelijk van hoe en waar een intent wordt gestart.
Voor cross-origin-verzoeken is een extra beveiligingslaag vereist, omdat de client en de server niet eigendom zijn van dezelfde partij. In deze handleiding wordt besproken hoe je dergelijke verzoeken start via aangepaste Chrome-tabbladen, dat wil zeggen intents die worden gestart vanuit apps die een URL openen op het browsertabblad. Tot Chrome 83 konden ontwikkelaars alle kopteksten toevoegen bij het starten van een aangepast tabblad. Vanaf versie 83 filtert Chrome alle cross-origin-headers, behalve die op de toelatingslijst, omdat headers die niet op de toelatingslijst staan een beveiligingsrisico vormen. Vanaf Chrome 86 is het mogelijk om headers die niet op de toelatingslijst staan, toe te voegen aan cross-origin-verzoeken als de server en de client aan elkaar zijn gerelateerd via een Digital Asset Link. Dit gedrag wordt samengevat in de volgende tabel:
| Chrome-versie | CORS-headers toegestaan |
|---|---|
| vóór Chrome 83 | op de toelatingslijst, niet op de toelatingslijst |
| Chrome 83 tot en met Chrome 85 | op de toelatingslijst |
| vanaf Chrome 86 | op de toelatingslijst, niet op de toelatingslijst als er een link naar een digitaal item is ingesteld |
Tabel 1: Filteren van CORS-headers die niet op de toelatingslijst staan.
In dit artikel wordt uitgelegd hoe je een geverifieerde verbinding tussen de server en de client instelt en deze gebruikt om zowel op de toelatingslijst geplaatste als niet op de toelatingslijst geplaatste HTTP-headers te sturen. Je kunt naar Extra koppen toevoegen aan aangepaste tabblad-intents gaan voor de code.
Achtergrond
CORS-verzoekheaders op de toelatingslijst versus niet op de toelatingslijst
Met Cross-Origin Resource Sharing (CORS) kan een web-app van de ene oorsprong resources van een andere oorsprong aanvragen. De lijst met headers die op de CORS-toelatingslijst staan, wordt bijgehouden in de HTML-standaard. In de volgende tabel staan voorbeelden van headers op de toelatingslijst:
| Header | Beschrijving |
|---|---|
| accept-language | kondigt natuurlijke talen aan die de client begrijpt |
| content-language | beschrijft taal die bedoeld is voor de huidige doelgroep |
| contenttype | geeft het mediatype van de bron aan |
Tabel 2: Voorbeeld van CORS-headers op de toelatingslijst.
De op de toelatingslijst geplaatste headers worden als veilig beschouwd omdat ze geen gevoelige gebruikersinformatie bevatten en het onwaarschijnlijk is dat ze de server ertoe aanzetten mogelijk schadelijke bewerkingen uit te voeren.
In de volgende tabel staan voorbeelden van headers die niet op de toelatingslijst staan:
| Header | Beschrijving |
|---|---|
| dragertoken | verifieert de client op een server |
| oorsprong | geeft de oorsprong van het verzoek aan |
| koekje | bevat cookies die zijn ingesteld door de server |
Tabel 3: Voorbeeld van CORS-headers die niet op de toelatingslijst staan.
Het toevoegen van niet-toegestane headers aan CORS-verzoeken wordt afgeraden door de HTML-standaard en servers gaan ervan uit dat cross-origin-verzoeken alleen toegestane headers bevatten. Als je headers die niet op de toelatingslijst staan, stuurt vanuit cross-origin domeinen, kunnen schadelijke apps van derden headers maken die misbruik maken van gebruikerscookies die Chrome (of een andere browser) opslaat en aan verzoeken toevoegt. De cookies kunnen schadelijke servertransacties verifiëren die anders niet mogelijk zouden zijn.
CORS-headers op de toelatingslijst toevoegen aan verzoeken voor aangepaste tabbladen
Aangepaste tabbladen zijn een speciale manier om webpagina's te openen in een aangepast browsertabblad. Intents voor aangepaste tabbladen kunnen worden gemaakt met CustomTabsIntent.Builder(). Je kunt ook headers aan deze intents toevoegen met een Bundle met de markering 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"));
We kunnen altijd headers op de toelatingslijst toevoegen aan CORS-verzoeken voor aangepaste tabbladen. Chrome filtert standaard headers die niet op de toelatingslijst staan. Hoewel andere browsers zich anders kunnen gedragen, moeten ontwikkelaars verwachten dat headers die niet op de toelatingslijst staan, over het algemeen worden geblokkeerd.
De ondersteunde manier om headers die niet op de toelatingslijst staan op te nemen in aangepaste tabbladen, is door eerst de cross-origin-verbinding te verifiëren met een digitale toegangslink. In het volgende gedeelte staat hoe je deze instelt en een Custom Tabs-intent start met de vereiste headers.
Extra headers toevoegen aan intents voor aangepaste tabbladen
Digital Asset Links instellen
Als je wilt toestaan dat headers die niet op de toelatingslijst staan, worden doorgegeven via Custom Tab-intents, moet je een link naar een digitaal item instellen tussen de Android- en web-app die verifieert dat de auteur eigenaar is van beide apps.
Volg de officiële gids om een Digital Asset Link in te stellen. Gebruik voor de linkrelatie "delegate_permission/common.use_as_origin"` om aan te geven dat beide apps tot dezelfde oorsprong behoren nadat de link is geverifieerd.
Intentie voor aangepast tabblad maken met extra koppen
Je kunt op meerdere manieren een intentie voor aangepaste tabbladen maken. Je kunt de builder gebruiken die beschikbaar is in androidX door de bibliotheek toe te voegen aan de build-afhankelijkheden:
implementation 'androidx.browser:browser:1.2.0'
Maak de intentie en voeg extra headers toe:
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;
}
Een verbinding met aangepaste tabbladen instellen om de componentlink te valideren
Een verbinding met aangepaste tabbladen wordt gebruikt om een CustomTabsSession in te stellen tussen de app en het Chrome-tabblad. We hebben de sessie nodig om te verifiëren dat de app en de web-app dezelfde oorsprong hebben.
De verificatie slaagt alleen als de links naar digitale items correct zijn ingesteld.
We raden je aan CustomTabsClient.warmup() te bellen. Hiermee kan de browser-app vooraf worden geïnitialiseerd op de achtergrond en wordt het proces om de URL te openen versneld.
// 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) { }
};
Een callback instellen die de intentie start na validatie
De CustomTabsCallback is doorgegeven aan de sessie. We hebben de onRelationshipValidationResult() ingesteld om de eerder gemaakte CustomTabsIntent te starten zodra de oorsprongverificatie is geslaagd.
// 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));
}
};
De serviceverbinding voor aangepaste tabbladen binden
Als je de service bindt, wordt de service gestart en wordt de onCustomTabsServiceConnected() van de verbinding uiteindelijk aangeroepen. Vergeet niet de service op de juiste manier te ontbinden. Binding en ontbinding
wordt meestal gedaan in de methoden voor de levenscyclus van activiteit onStart() en 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);
Demo-app-code
Hier vind je meer informatie over de Custom Tabs-service. Ga naar de GitHub-repository android-browser-helper voor een werkende voorbeeld-app.
Overzicht
In deze handleiding wordt uitgelegd hoe je willekeurige headers toevoegt aan CORS-verzoeken voor aangepaste tabbladen. Headers op de toelatingslijst kunnen aan elk CORS-verzoek voor aangepaste tabbladen worden toegevoegd. Headers die niet op de toelatingslijst staan, worden over het algemeen als onveilig beschouwd in CORS-verzoeken en Chrome filtert ze standaard. Ze bijvoegen is alleen toegestaan voor clients en servers van dezelfde oorsprong, geverifieerd door een Digital Asset Link.