Niektóre z opisanych tu aktualizacji zostały wyjaśnione podczas sesji Google I/O Bezpieczne i płynne logowanie: utrzymywanie zaangażowania użytkowników:
Chrome 57
W Chrome 57 wprowadziliśmy tę ważną zmianę w interfejsie Credential Management API.
Dane logowania można udostępniać z innej subdomeny
Chrome może teraz pobierać dane logowania przechowywane w innej subdomenie za pomocą interfejsu Credential Management API.
Jeśli na przykład hasło jest przechowywane w login.example.com, skrypt w www.example.com może wyświetlić je jako jeden z elementów konta w oknie wyboru konta.
Musisz jawnie zapisać hasło za pomocą navigator.credentials.store(),
aby po wybraniu przez użytkownika danych logowania przez kliknięcie okna
hasło zostało przekazane i skopiowane do bieżącego źródła.
Po zapisaniu hasło jest dostępne jako dane logowania w tym samym miejscu pochodzenia (www.example.com).
Na zrzucie ekranu poniżej dane logowania przechowywane w login.aliexpress.com są widoczne dla m.aliexpress.com i dostępne dla użytkownika:
Chrome 60
Chrome 60 wprowadza kilka ważnych zmian w interfejsie Credential Management API:
Niestandardowa funkcja
fetch()nie jest już wymagana do pobierania hasła, więc wkrótce zostanie wycofana.navigator.credentials.get()akceptuje teraz typ wyliczeniowymediationzamiast flagi logicznejunmediated.Zmieniono nazwę pliku
requireUserMediation()napreventSilentAccess().Nowa metoda
navigator.credentials.create()asynchronicznie tworzy obiekty danych logowania.
Wykrywanie funkcji wymaga uwagi
Aby sprawdzić, czy interfejs Credential Management API umożliwiający dostęp do danych logowania opartych na hasłach i danych logowania sfederowanych jest dostępny, sprawdź, czy dostępny jest window.PasswordCredential lub window.FederatedCredential.
if (window.PasswordCredential || window.FederatedCredential) {
// The Credential Management API is available
}
Obiekt PasswordCredential zawiera teraz hasło
Interfejs Credential Management API stosował konserwatywne podejście do obsługi haseł.
Ukrywało hasła przed JavaScriptem, wymagając od deweloperów wysyłania obiektu PasswordCredential bezpośrednio na serwer w celu weryfikacji za pomocą rozszerzenia interfejsu API fetch().
Takie podejście wiązało się jednak z pewnymi ograniczeniami. Otrzymaliśmy opinie, że deweloperzy nie mogli korzystać z interfejsu API, ponieważ:
Musieli wysłać hasło jako część obiektu JSON.
Musieli wysłać wartość skrótu hasła na swój serwer.
Po przeprowadzeniu analizy bezpieczeństwa i stwierdzeniu, że ukrywanie haseł przed JavaScriptem nie zapobiega wszystkim wektorom ataku tak skutecznie, jak się spodziewaliśmy, postanowiliśmy wprowadzić zmianę.
Interfejs Credential Management API zawiera teraz nieprzetworzone hasło w zwracanym obiekcie danych logowania, dzięki czemu masz do niego dostęp w formie zwykłego tekstu. Możesz użyć dotychczasowych metod, aby dostarczyć informacje o danych logowania na serwer:
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
mediation: 'silent'
}).the>n(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);
});
Pobieranie niestandardowe zostanie wkrótce wycofane
Aby sprawdzić, czy używasz niestandardowej funkcji fetch(), sprawdź, czy używa ona obiektu PasswordCredential lub FederatedCredential jako wartości właściwości credentials, na przykład:
fetch('/signin', {
method: 'POST',
credentials: c
})
Zalecamy użycie zwykłej funkcji fetch(), jak pokazano w poprzednim przykładzie kodu, lub funkcji XMLHttpRequest.
navigator.credentials.get() akceptuje teraz zapośredniczenie typu wyliczeniowego
Do wersji Chrome 60 navigator.credentials.get() akceptował opcjonalną właściwość unmediated z flagą logiczną. Na przykład:
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
unmediated: true
}).>then(c = {
// Sign-in
});
Ustawienie unmediated: true uniemożliwia przeglądarce wyświetlanie selektora konta podczas przekazywania danych logowania.
Flaga została rozszerzona jako zapośredniczenie. Zapośredniczenie użytkownika może nastąpić, gdy:
Użytkownik musi wybrać konto, na które chce się zalogować.
Użytkownik chce się zalogować po wywołaniu
navigator.credentials.requireUseMediation().
Wybierz jedną z tych opcji dla wartości mediation:
Wartość mediation |
W porównaniu z flagą logiczną | Zachowanie | |
|---|---|---|---|
silent |
Równe unmediated: true |
Dane logowania zostały przekazane bez wyświetlania Account Chooser. | |
optional |
Równe unmediated: false |
Wyświetla selektor konta, jeśli wcześniej wywołano funkcję preventSilentAccess(). |
|
required |
Nowa opcja | Zawsze pokazuj wybór konta. Przydatne, gdy chcesz umożliwić użytkownikowi przełączenie konta za pomocą natywnego okna wyboru konta. |
W tym przykładzie dane logowania są przekazywane bez wyświetlania Account Chooser, co odpowiada poprzedniej fladze unmediated: true:
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
mediation: 'silent&>#39;
}).then(c = {
// Sign-in
});
Zmieniono nazwę z requireUserMediation() na preventSilentAccess()
Aby dopasować do nowej właściwości mediation oferowanej w wywołaniu get(), zmieniliśmy nazwę metody navigator.credentials.requireUserMediation() na navigator.credentials.preventSilentAccess().
Zmieniona nazwa metody uniemożliwia przekazywanie danych logowania bez wyświetlania selektora konta (czasami nazywanego bez pośrednictwa użytkownika). Jest to przydatne, gdy użytkownik wyloguje się z witryny lub wyrejestruje się z niej i nie chce być automatycznie logowany przy następnej wizycie.
signoutUser();
if (navigator.credentials) {
navigator.credentials.preventSilentAccess();
}
Asynchroniczne tworzenie obiektów danych logowania za pomocą nowej metody navigator.credentials.create()
Teraz możesz tworzyć obiekty danych logowania asynchronicznie za pomocą nowej metody navigator.credentials.create().
Poniżej znajdziesz porównanie podejścia synchronicznego i asynchronicznego.
Tworzenie obiektu PasswordCredential
Metoda synchronizacji
let c = new PasswordCredential(form);
Podejście asynchroniczne (nowe)
let c = await navigator.credentials.create({
password: form
});
lub
let c = await navigator.credentials.create({
password: {
id: id,
password: password
}
});
Tworzenie obiektu FederatedCredential
Metoda synchronizacji
let c = new FederatedCredential({
id: 'agektmr',
name: 'Eiji Kitamura',
provider: 'https://accounts.google.com',
iconURL: 'https://*****'
});
Podejście asynchroniczne (nowość)
let c = await navigator.credentials.create({
federated: {
id: 'agektmr',
name: 'Eiji Kitamura',
provider: 'https://accounts.google.com',
iconURL: 39;https://*****'
}
});
Przewodnik po migracji
Masz już wdrożony interfejs Credential Management API? Aby przejść na nową wersję, możesz skorzystać z przewodnika po migracji.