Nieuwste updates voor de API voor referentiebeheer

Enkele van de hier beschreven updates worden uitgelegd in de Google I/O-sessie, Veilig en naadloos aanmelden: gebruikers betrokken houden :

Chroom 57

Chrome 57 introduceerde deze belangrijke wijziging in de Credential Management API .

Inloggegevens kunnen worden gedeeld vanaf een ander subdomein

Chrome kan nu een referentie ophalen die is opgeslagen in een ander subdomein met behulp van de Credential Management API . Als een wachtwoord bijvoorbeeld is opgeslagen in login.example.com , kan een script op www.example.com dit weergeven als een van de accountitems in het dialoogvenster Account kiezen.

U moet het wachtwoord expliciet opslaan met behulp van navigator.credentials.store() , zodat wanneer een gebruiker een referentie kiest door op het dialoogvenster te tikken, het wachtwoord wordt doorgegeven en gekopieerd naar de huidige oorsprong.

Zodra het wachtwoord is opgeslagen, is het vanaf dezelfde locatie www.example.com ) beschikbaar als referentie.

In de onderstaande schermafbeelding zijn de inloggegevens die zijn opgeslagen onder login.aliexpress.com zichtbaar voor m.aliexpress.com en kan de gebruiker uit de volgende opties kiezen:

Accountkiezer toont geselecteerde subdomein-inloggegevens

Chroom 60

Chrome 60 introduceert een aantal belangrijke wijzigingen in de Credential Management API :

Kenmerkendetectie vereist aandacht

Om te zien of de Credential Management API voor toegang tot wachtwoordgebaseerde en gefedereerde referenties beschikbaar is, controleert u of window.PasswordCredential of window.FederatedCredential beschikbaar is.

if (window.PasswordCredential || window.FederatedCredential) {
  // The Credential Management API is available
}

PasswordCredential -object bevat nu het wachtwoord

De Credential Management API hanteerde een conservatieve benadering voor het verwerken van wachtwoorden. Deze verborg wachtwoorden voor JavaScript, waardoor ontwikkelaars het PasswordCredential object rechtstreeks naar hun server moesten sturen voor validatie via een uitbreiding van de fetch() API.

Maar deze aanpak bracht een aantal beperkingen met zich mee. We kregen feedback dat ontwikkelaars de API niet konden gebruiken omdat:

  • Ze moesten het wachtwoord als onderdeel van een JSON-object versturen.

  • Ze moesten de hashwaarde van het wachtwoord naar hun server sturen.

Nadat we een beveiligingsanalyse hadden uitgevoerd en hadden geconstateerd dat het verbergen van wachtwoorden in JavaScript niet alle aanvalsvectoren zo effectief tegenhield als we hadden gehoopt, hebben we besloten een wijziging door te voeren.

De Credential Management API bevat nu een onbewerkt wachtwoord in een geretourneerd object met referentiegegevens, zodat u er als platte tekst toegang toe hebt. U kunt bestaande methoden gebruiken om referentiegegevens naar uw server te sturen:

navigator.credentials.get({
    password: true,
    federated: {
    providers: [ 'https://accounts.google.com' ]
    },
    mediation: 'silent'
}).then(passwordCred => {
    if (passwordCred) {
    let form = new FormData();
    form.append('email', passwordCred.id);
    form.append('password', passwordCred.password);
    form.append('csrf_token', csrf_token);
    return fetch('/signin', {
        method: 'POST',
        credentials: 'include',
        body: form
    });
    } else {

    // Fallback to sign-in form
    }
}).then(res => {
    if (res.status === 200) {
    return res.json();
    } else {
    throw 'Auth failed';
    }
}).then(profile => {
    console.log('Auth succeeded', profile);
});

Aangepast ophalen wordt binnenkort afgeschaft

Om te bepalen of u een aangepaste fetch() functie gebruikt, controleert u of deze een PasswordCredential object of een FederatedCredential object gebruikt als waarde van de eigenschap credentials , bijvoorbeeld:

fetch('/signin', {
    method: 'POST',
    credentials: c
})

Het is raadzaam om een ​​gewone fetch() functie te gebruiken, zoals getoond in het vorige codevoorbeeld, of om een XMLHttpRequest te gebruiken.

Tot Chrome 60 accepteerde navigator.credentials.get() een optionele unmediated eigenschap met een booleaanse vlag. Bijvoorbeeld:

navigator.credentials.get({
    password: true,
    federated: {
    providers: [ 'https://accounts.google.com' ]
    },
    unmediated: true
}).then(c => {

    // Sign-in
});

Met de instelling unmediated: true wordt voorkomen dat de browser de accountkiezer weergeeft bij het doorgeven van referenties.

De vlag is nu uitgebreid als bemiddeling. Gebruikersbemiddeling kan plaatsvinden wanneer:

  • Een gebruiker moet een account kiezen waarmee hij zich wil aanmelden.

  • Een gebruiker wil zich expliciet aanmelden na de aanroep navigator.credentials.requireUseMediation() .

Kies een van de volgende opties voor de mediation :

mediation Vergeleken met de Booleaanse vlag Gedrag
silent Is gelijk aan unmediated: true De inloggegevens zijn doorgegeven zonder dat er een accountkiezer wordt weergegeven.
optional Is gelijk aan unmediated: false Geeft een accountkiezer weer als preventSilentAccess() eerder is aangeroepen.
required Een nieuwe optie Altijd een accountkiezer weergeven. Handig wanneer u een gebruiker wilt laten wisselen van account via het standaard accountkiezervenster.

In dit voorbeeld worden de referenties doorgegeven zonder dat er een accountkiezer wordt getoond, het equivalent van de vorige vlag, unmediated: true :

navigator.credentials.get({
    password: true,
    federated: {
    providers: [ 'https://accounts.google.com' ]
    },
    mediation: 'silent'
}).then(c => {

    // Sign-in
});

requireUserMediation() hernoemd naar preventSilentAccess()

Om het goed aan te laten sluiten bij de nieuwe mediation eigenschap die wordt aangeboden in de get() aanroep, is de naam van de navigator.credentials.requireUserMediation() -methode gewijzigd in navigator.credentials.preventSilentAccess() .

De hernoemde methode voorkomt dat een referentie wordt doorgegeven zonder de accountkiezer te tonen (soms aangeroepen zonder tussenkomst van de gebruiker). Dit is handig wanneer een gebruiker zich afmeldt bij een website of zich afmeldt en niet automatisch opnieuw wil worden aangemeld bij het volgende bezoek.

signoutUser();
if (navigator.credentials) {
    navigator.credentials.preventSilentAccess();
}

Creëer asynchroon referentieobjecten met de nieuwe methode navigator.credentials.create()

U kunt nu credential-objecten asynchroon maken met de nieuwe methode navigator.credentials.create() . Lees verder voor een vergelijking tussen de sync- en async-benadering.

Een PasswordCredential object maken

Sync-benadering
let c = new PasswordCredential(form);
Asynchrone aanpak (nieuw)
let c = await navigator.credentials.create({
    password: form
});

of:

let c = await navigator.credentials.create({
    password: {
    id: id,
    password: password
    }
});

Een FederatedCredential -object maken

Sync-benadering
let c = new FederatedCredential({
    id:       'agektmr',
    name:     'Eiji Kitamura',
    provider: 'https://accounts.google.com',
    iconURL:  'https://*****'
});
Asynchrone aanpak (nieuw)
let c = await navigator.credentials.create({
    federated: {
    id:       'agektmr',
    name:     'Eiji Kitamura',
    provider: 'https://accounts.google.com',
    iconURL:  'https://*****'
    }
});

Migratiegids

Heeft u al een implementatie van de Credential Management API? We hebben een migratiehandleiding die u kunt volgen om te upgraden naar de nieuwe versie.