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 wpisywanie haseł bywa jednak uciążliwe dla użytkowników, zwłaszcza na ekranach urządzeń mobilnych, co prowadzi do używania tych samych haseł na różnych stronach. Jest to oczywiście ryzyko 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()
Te proste interfejsy API pozwalają programistom na:
- Umożliw użytkownikom logowanie się jednym kliknięciem.
- Zapamiętaj konto federacyjne, 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ą synchronizować hasła na różnych urządzeniach. Takie zsynchronizowane hasła można też udostępniać aplikacjom na Androida zintegrowanym z interfejsem API Smart Lock na hasła na Androida dla wygody użytkowników na wielu 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?
Uwzględnienie wszystkich tych przypadków jest praktycznie niemożliwe, ale przyjrzyjmy się typowej aplikacji jednostronicowej.
- Pierwsza strona to formularz rejestracji.
- Kliknięcie przycisku „Zaloguj się” spowoduje otwarcie formularza logowania.
- Zarówno formularze rejestracji, jak i logowania zawierają typowe opcje identyfikatora/hasła oraz uwierzytelniania federacyjnego, np. logowania Google i logowania 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ę”.
- Przechowywanie danych logowania: po udanym logowaniu zaproponuj zapisanie danych logowania w menedżerze haseł przeglądarki do późniejszego wykorzystania.
- 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.
Pokazuj wybór konta 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 pokaże interfejs wyboru konta, w którym 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 dokona wyboru konta, funkcja rozpoznawania otrzyma dane logowania do hasła. 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 korzysta z atrybutów autocomplete
, aby automatycznie mapować elementy 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 logowanie się
Gdy użytkownik opuszcza witrynę i wróci do niej później, sesja może wygasnąć. 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. Spełnia kilka warunków:
- 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ą.
Aby włączyć tryb zapośredniczenia, wywołaj metodę 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żesz uzyskać tylko w ramach usługi PasswordCredential
. Nie są one w żaden sposób ujawniane.
Czy można zapisać 3 zbiory cyfr identyfikatora za pomocą interfejsu Credential Management API? Obecnie nie. Chętnie poznamy Twoją 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 do Chrome z interfejsem Credential Management API?
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.