Uproszczenie procesu logowania za pomocą interfejsu API do zarządzania danymi logowania

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 demonstracyjnejprzykł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.

Wyświetla się interfejs wyboru konta, w którym użytkownik może wybrać konto, na które chce się zalogować.
Wyświetla się interfejs wyboru konta, w którym użytkownik może wybrać konto, na które chce się zalogować

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().

gdy w menedżerze haseł jest zapisanych wiele kont;
Gdy w menedżerze haseł jest zapisanych kilka kont
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
Schemat blokowy zarządzania danymi logowania

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ć.

Chrome pyta użytkowników, czy chcą zapisać dane logowania (lub dostawcę federacji).
Chrome pyta użytkowników, czy chcą zapisać dane logowania (lub dostawcę federacji)

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
});
Diagram procesu logowania.

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ę.

Gdy użytkownik zostanie automatycznie zalogowany, pojawi się powiadomienie.
Gdy użytkownik zaloguje się automatycznie, pojawi się powiadomienie.

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.

Diagram przepływu danych obiektu danych logowania

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();
Schemat blokowy logowania automatycznego

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.