Aby zapewnić użytkownikom wygodę korzystania z witryny, warto pomóc im w uwierzytelnieniu się. Użytkownicy uwierzytelnieni mogą wchodzić w interakcje z innymi użytkownikami za pomocą dedykowanego profilu, synchronizować dane na różnych urządzeniach lub przetwarzać dane w trybie offline. A to tylko niektóre z możliwości. Tworzenie, zapamiętywanie i pisanie haseł jest jednak kłopotliwe dla użytkowników, zwłaszcza na ekranach urządzeń mobilnych. W rezultacie często używają oni tych samych haseł w różnych witrynach. To oczywiście stwarza zagrożenie dla bezpieczeństwa.
Najnowsza wersja Chrome (51) obsługuje interfejs Credential Management API. Jest to propozycja standardów W3C, która daje deweloperom dostęp programowy do menedżera danych logowania w przeglądarce i ułatwia użytkownikom logowanie.
Czym jest interfejs Credential Management API?
Interfejs Credential Management API umożliwia programistom przechowywanie i pobieranie danych logowania z hasłem oraz danych logowania federacyjnych. Zawiera 3 funkcje:
navigator.credentials.get()
navigator.credentials.store()
navigator.credentials.requireUserMediation()
Dzięki tym prostym interfejsom API deweloperzy mogą wykonywać zaawansowane operacje, takie jak:
- Umożliw użytkownikom logowanie się jednym kliknięciem.
- Zapamiętaj konto z federacją, którego użył użytkownik do zalogowania się.
- Po upływie sesji zaloguj użytkowników ponownie.
W przypadku implementacji w Chrome dane uwierzytelniające będą przechowywane w menedżerze haseł Chrome. Jeśli użytkownicy są zalogowani w Chrome, mogą zsynchronizować hasła na różnych urządzeniach. Zsynchronizowane hasła można też udostępniać aplikacjom na Androida, które zintegrowały interfejs API Smart Lock na hasła na Androida. Dzięki temu można korzystać z haseł na różnych platformach.
Integracja interfejsu Credential Management API z witryną
Sposób korzystania z interfejsu Credential Management API w przypadku witryny może się różnić w zależności od jej architektury. Czy to aplikacja jednostronicowa? Czy jest to starsza architektura z przejściami między stronami? Czy formularz logowania znajduje się tylko na stronie głównej? Czy przyciski logowania są dostępne wszędzie? Czy użytkownicy mogą przeglądać Twoją witrynę bez logowania się? Czy federacja działa w oknach wyskakujących? Czy wymaga interakcji na wielu stronach?
Nie da się uwzględnić wszystkich tych przypadków, ale przyjrzyjmy się typowej aplikacji jednostronicowej.
- Pierwsza strona to formularz rejestracji.
- Po kliknięciu przycisku „Zaloguj się” użytkownicy przejdą do formularza logowania.
- Zarówno formularze rejestracji, jak i logowania zawierają typowe opcje identyfikatora/hasła oraz poświadczeń i federacji, np. logowanie przez Google i Facebooka.
Za pomocą interfejsu API do zarządzania danymi logowania możesz dodać do witryny takie funkcje jak:
- Pokaż selektor kont podczas logowania: wyświetla natywny interfejs selektora kont, gdy użytkownik kliknie „Zaloguj się”.
- Zapisz dane logowania: po pomyślnym zalogowaniu się możesz zapisać informacje o danych logowania w menedżerze haseł przeglądarki, aby korzystać z nich później.
- Zezwalaj użytkownikowi na automatyczne logowanie: zezwalaj użytkownikowi na ponowne zalogowanie się, jeśli sesja wygasła.
- Mediate auto sign-in: gdy użytkownik się wyloguje, wyłącz automatyczne logowanie na czas jego następnej wizyty.
Te funkcje możesz wypróbować w witrynie demonstracyjnej z przykładowym kodem.
wyświetlać selektor kont podczas logowania,
Po kliknięciu przez użytkownika przycisku „Zaloguj się” i przejściu do formularza logowania możesz użyć funkcji navigator.credentials.get(), aby pobrać informacje o danych logowania. Chrome wyświetli interfejs wyboru konta, z którego użytkownik może wybrać konto.
Pobieranie obiektu danych logowania z hasłem
Aby wyświetlić dane logowania jako opcje konta, użyj password: true
.
navigator.credentials.get({
password: true, // `true` to obtain password credentials
}).then(function(cred) {
// continuation
...
Logowanie się przy użyciu hasła
Gdy użytkownik wybierze konto, funkcja rozwiązywania otrzyma dane logowania. Możesz go wysłać na serwer za pomocą fetch()
:
// continued from previous example
}).then(function(cred) {
if (cred) {
if (cred.type == 'password') {
// Construct FormData object
var form = new FormData();
// Append CSRF Token
var csrf_token = document.querySelector('csrf_token').value;
form.append('csrf_token', csrf_token);
// You can append additional credential data to `.additionalData`
cred.additionalData = form;
// `POST` the credential object as `credentials`.
// id, password and the additional data will be encoded and
// sent to the url as the HTTP body.
fetch(url, { // Make sure the URL is HTTPS
method: 'POST', // Use POST
credentials: cred // Add the password credential object
}).then(function() {
// continuation
});
} else if (cred.type == 'federated') {
// continuation
Logowanie się za pomocą danych logowania sfederowanego
Aby wyświetlać użytkownikom konta z federacją, dodaj opcję federated
, która przyjmuje tablicę dostawców tożsamości, do opcji get()
.
navigator.credentials.get({
password: true, // `true` to obtain password credentials
federated: {
providers: [ // Specify an array of IdP strings
'https://accounts.google.com',
'https://www.facebook.com'
]
}
}).then(function(cred) {
// continuation
...
Możesz sprawdzić właściwość type
obiektu danych logowania, aby dowiedzieć się, czy są to dane PasswordCredential
(type == 'password'
) czy FederatedCredential
(type == 'federated'
). Jeśli dane logowania to FederatedCredential
, możesz wywołać odpowiedni interfejs API, korzystając z zawartych w nich informacji.
});
} else if (cred.type == 'federated') {
// `provider` contains the identity provider string
switch (cred.provider) {
case 'https://accounts.google.com':
// Federated login using Google Sign-In
var auth2 = gapi.auth2.getAuthInstance();
// In Google Sign-In library, you can specify an account.
// Attempt to sign in with by using `login_hint`.
return auth2.signIn({
login_hint: cred.id || ''
}).then(function(profile) {
// continuation
});
break;
case 'https://www.facebook.com':
// Federated login using Facebook Login
// continuation
break;
default:
// show form
break;
}
}
// if the credential is `undefined`
} else {
// show form
Przechowywanie danych logowania
Gdy użytkownik loguje się w witrynie za pomocą formularza, możesz użyć funkcji navigator.credentials.store(), aby zapisać dane logowania. Użytkownik zostanie poproszony o zapisanie pliku. W zależności od typu danych logowania użyj funkcji new
PasswordCredential()
lub new
FederatedCredential()
, aby utworzyć obiekt danych logowania, który chcesz przechowywać.
Tworzenie i przechowywanie danych logowania w postaci hasła na podstawie elementu formularza
Podany niżej kod używa atrybutów autocomplete
do automatycznego mapowania elementów formularza na parametry obiektu PasswordCredential.
HTML
html
<form id="form" method="post">
<input type="text" name="id" autocomplete="username" />
<input type="password" name="password" autocomplete="current-password" />
<input type="hidden" name="csrf_token" value="******" />
</form>
JavaScript
var form = document.querySelector('\#form');
var cred = new PasswordCredential(form);
// Store it
navigator.credentials.store(cred)
.then(function() {
// continuation
});
Tworzenie i przechowywanie danych logowania w ramach federacji
// After a federation, create a FederatedCredential object using
// information you have obtained
var cred = new FederatedCredential({
id: id, // The id for the user
name: name, // Optional user name
provider: 'https://accounts.google.com', // A string that represents the identity provider
iconURL: iconUrl // Optional user avatar image url
});
// Store it
navigator.credentials.store(cred)
.then(function() {
// continuation
});
Zezwalanie użytkownikowi na automatyczne ponowne zalogowanie się
Gdy użytkownik opuści Twoją witrynę i wróci do niej później, możliwe, że sesja wygasła. Nie zmuszaj użytkownika do wpisywania hasła za każdym razem, gdy wraca na stronę. Zezwalanie użytkownikowi na automatyczne logowanie się.
Pobieranie obiektu danych logowania
navigator.credentials.get({
password: true, // Obtain password credentials or not
federated: { // Obtain federation credentials or not
providers: [ // Specify an array of IdP strings
'https://accounts.google.com',
'https://www.facebook.com'
]
},
unmediated: true // `unmediated: true` lets the user automatically sign in
}).then(function(cred) {
if (cred) {
// auto sign-in possible
...
} else {
// auto sign-in not possible
...
}
});
Kod powinien wyglądać podobnie do tego, który widzisz w sekcji „Pokaż selektor kont podczas logowania”. Jedyną różnicą jest to, że musisz ustawić unmediated: true
.
Spowoduje to natychmiastowe rozwiązanie problemu i udzielenie Ci poświadczeń umożliwiających automatyczne logowanie użytkownika. Wymagane są 2 warunki:
- Użytkownik potwierdził, że zapoznał się z funkcją automatycznego logowania w ramach sekcji powitalnej.
- Użytkownik zalogował się wcześniej na stronie internetowej za pomocą interfejsu Credential Management API.
- Użytkownik ma tylko 1 zestaw danych logowania zapisany dla Twojego źródła.
- Użytkownik nie wylogował się w poprzedniej sesji.
Jeśli którykolwiek z tych warunków nie zostanie spełniony, funkcja zostanie odrzucona.
Pośrednictwo w logowaniu automatycznym
Gdy użytkownik wyloguje się z Twojej witryny, Twoim obowiązkiem jest upewnienie się, że nie zaloguje się automatycznie ponownie. W tym celu interfejs API zarządzania danymi logowania udostępnia mechanizm zwany mediacją.
Tryb pośredniczenia możesz włączyć, dzwoniąc pod numer navigator.credentials.requireUserMediation()
.
Dopóki stan pośrednictwa użytkownika dla źródła jest włączony, funkcja unmediated: true
z użyciem navigator.credentials.get()
będzie zwracać wartość undefined
.
Pośrednictwo w logowaniu automatycznym
navigator.credentials.requireUserMediation();
Najczęstsze pytania
Czy kod JavaScript w witrynie może pobrać hasło w postaci zwykłego tekstu?
Nie. Hasła można uzyskać tylko w ramach PasswordCredential
i nie można ich w żaden sposób ujawnić.
Czy można zapisać 3 zbiory cyfr identyfikatora za pomocą interfejsu Credential Management API? Obecnie nie. Będziemy wdzięczni za opinię na temat specyfikacji.
Czy mogę używać interfejsu Credential Management API w elemencie iframe?
Interfejs API jest ograniczony do kontekstów najwyższego poziomu. Wywołania funkcji .get()
lub .store()
w ramce iframe zostaną natychmiast rozwiązane bez efektu.
Czy mogę zintegrować rozszerzenie do zarządzania hasłami w Chrome z interfejsem API zarządzania danymi logowania?
Możesz zastąpić navigator.credentials
i podłączyć go do rozszerzenia Chrome, aby uzyskać dane logowania get()
lub store()
.
Zasoby
Więcej informacji o interfejsie Credential Management API znajdziesz w przewodniku integracji.
- Specyfikacja interfejsu API
- Dyskusje i opinie dotyczące specyfikacji
- Dokumentacja interfejsu MDN API
- Przewodnik po integracji interfejsu Credential Management API
- Prezentacja
- Kod źródłowy wersji demonstracyjnej
- Codelab „Włączanie automatycznego logowania za pomocą interfejsu Credential Management API”