Niektóre opisane tu aktualizacje zostały omówione na konferencji Google I/O, Bezpieczne i łatwe logowanie: dbanie o zaangażowanie użytkowników:
Chrome 57
Ta ważna zmiana została wprowadzona w Chrome 57 Credential Management API.
Dane logowania mogą być udostępniane z innej subdomeny
Chrome może teraz pobrać dane logowania zapisane w innej subdomenie przy użyciu
Credential Management API.
Jeśli na przykład hasło jest przechowywane w usłudze login.example.com
,
skrypt w systemie www.example.com
może go wyświetlić jako jeden z elementów konta w oknie wyboru konta.
Musisz bezpośrednio zapisać hasło za pomocą właściwości navigator.credentials.store()
,
dzięki czemu, gdy użytkownik wybierze dane logowania, klikając w oknie,
hasło jest przekazywane i kopiowane do obecnego źródła.
Zapisze hasło będzie dostępne jako dane logowania
w tym samym punkcie początkowym www.example.com
i dalej.
Na zrzucie ekranu poniżej dane logowania są przechowywane w domenie login.aliexpress.com
jest widoczna dla usługi m.aliexpress.com
i użytkownik ma do wyboru następujące opcje:
![Selektor konta wyświetlający dane logowania do wybranej subdomeny](https://developer.chrome.com/static/blog/credential-management-updates/image/account-chooser-showing-s-369ff3f4bb61e.png?authuser=9&hl=pl)
Chrome 60
W Chrome 60 wprowadziliśmy kilka ważnych zmian Credential Management API:
Niestandardowa funkcja
fetch()
nie jest już wymagana do pobierania hasła, zostanie wkrótce wycofana.navigator.credentials.get()
akceptuje teraz wyliczeniemediation
zamiast flagi wartości logicznejunmediated
.Nazwa
requireUserMediation()
została zmieniona napreventSilentAccess()
.Nowa metoda
navigator.credentials.create()
asynchronicznie tworzy obiekty danych logowania.
Wykrywanie cech wymaga uwagi
Aby sprawdzić, czy interfejs Credential Management API do uzyskiwania dostępu do haseł
sfederowane dane logowania są dostępne. Sprawdź, czy window.PasswordCredential
lub
Adres window.FederatedCredential
jest dostępny.
if (window.PasswordCredential || window.FederatedCredential) {
// The Credential Management API is available
}
PasswordCredential
obiekt zawiera teraz hasło
Do obsługi haseł w interfejsie Credential Management API zastosowano zachowawcze podejście.
Ukrył hasła przed JavaScriptem, co wymagało od programistów
może wysłać obiekt PasswordCredential
bezpośrednio na serwer
do weryfikacji za pomocą rozszerzenia interfejsu API fetch()
.
Takie podejście skutkowało jednak szeregiem ograniczeń. Otrzymaliśmy informację, że deweloperzy nie mogą używać tego interfejsu API, ponieważ:
Musieć przesłać hasło w ramach obiektu JSON.
Musiał wysłać wartość skrótu hasła na swój serwer.
po przeprowadzeniu analizy zabezpieczeń i rozpoznaniu ukrycia haseł. nie powstrzymało wszystkich wektorów ataku tak skutecznie, jak się spodziewaliśmy, postanowiliśmy coś zmienić.
Interfejs Credential Management API zawiera teraz nieprzetworzone hasło w zwróconym obiekcie danych logowania, dzięki czemu masz do nich dostęp w postaci zwykłego tekstu. Możesz użyć istniejących metod, aby przesłać dane logowania na swój serwer:
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);
});
Niestandardowe pobieranie zostanie wkrótce wycofane
Aby sprawdzić, czy korzystasz z niestandardowej funkcji fetch()
,
Sprawdź, czy używa obiektu PasswordCredential
czy FederatedCredential
jako wartość właściwości credentials
, na przykład:
fetch('/signin', {
method: 'POST',
credentials: c
})
Używając zwykłej funkcji fetch()
, jak pokazano w poprzednim przykładzie kodu,
lub zalecana jest właściwość XMLHttpRequest
.
navigator.credentials.get()
akceptuje teraz zapośredniczenie wyliczeniowe
Do wersji Chrome 60
Użytkownik navigator.credentials.get()
zaakceptował 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 jest teraz przedłużona jako zapośredniczenie. Zapośredniczenie użytkownika może mieć miejsce, gdy:
Użytkownik musi wybrać konto, na które będzie się logować.
Użytkownik chce się zalogować po
navigator.credentials.requireUseMediation()
rozmowie.
Wybierz jedną z tych opcji wartości mediation
:
Wartość: mediation |
W porównaniu z flagą wartości logicznej | Zachowanie | |
---|---|---|---|
silent |
Równa się unmediated: true |
Dane logowania zostały przekazane bez wyświetlania selektora konta. | |
optional |
Równa się unmediated: false |
Wyświetla wybór konta, jeśli:
preventSilentAccess() wywołano wcześniej. |
|
required |
Nowa opcja | Zawsze pokazuj opcję wyboru konta. Przydatne, gdy chcesz umożliwić użytkownikowi przełączanie konta w natywnym oknie wyboru konta. |
W tym przykładzie
dane logowania są przekazywane bez wyświetlania selektora konta,
odpowiednik poprzedniej flagi, unmediated: true
:
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
mediation: 'silent'
}).then(c => {
// Sign-in
});
Zmieniono nazwę z requireUserMediation()
na preventSilentAccess()
Aby dopasować je do nowej właściwości mediation
oferowanej w wywołaniu get()
,
nazwa metody navigator.credentials.requireUserMediation()
została zmieniona na
navigator.credentials.preventSilentAccess()
Metoda ze zmienioną nazwą uniemożliwia przekazanie danych logowania bez wyświetlania selektora konta (czasami jest wywoływany bez zapośredniczenia użytkownika). Jest to przydatne, gdy użytkownik wyloguje się z witryny lub się wyrejestruje z jednego konta i nie chce logować się automatycznie przy następnej wizycie.
signoutUser();
if (navigator.credentials) {
navigator.credentials.preventSilentAccess();
}
Asynchronicznie twórz obiekty danych logowania za pomocą nowej metody navigator.credentials.create()
Teraz możesz asynchronicznie tworzyć obiekty danych logowania
za pomocą nowej metody: navigator.credentials.create()
.
W dalszej części artykułu znajdziesz porównanie metody synchronicznej i asynchronicznej.
Tworzenie obiektu PasswordCredential
Sposób 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
Sposób synchronizacji
let c = new FederatedCredential({
id: 'agektmr',
name: 'Eiji Kitamura',
provider: 'https://accounts.google.com',
iconURL: 'https://*****'
});
Podejście asynchroniczne (nowe)
let c = await navigator.credentials.create({
federated: {
id: 'agektmr',
name: 'Eiji Kitamura',
provider: 'https://accounts.google.com',
iconURL: 'https://*****'
}
});
Przewodnik po migracji
Masz już wdrożenie interfejsu Credential Management API? Przygotowaliśmy dokument z przewodnikiem po migracji. .