Оптимизация процесса входа в систему с помощью API управления учетными данными

Чтобы обеспечить удобство взаимодействия с пользователем, важно помочь пользователям аутентифицироваться на вашем веб-сайте. Аутентифицированные пользователи могут взаимодействовать друг с другом, используя специальный профиль, синхронизировать данные между устройствами или обрабатывать данные в автономном режиме; список можно продолжать и продолжать. Но создание, запоминание и ввод паролей, как правило, является обременительным для конечных пользователей, особенно на экранах мобильных устройств, что приводит к повторному использованию одних и тех же паролей на разных сайтах. Это, конечно, угроза безопасности.

Последняя версия Chrome (51) поддерживает API управления учетными данными . Это стандартное предложение W3C, которое предоставляет разработчикам программный доступ к диспетчеру учетных данных браузера и помогает пользователям более легко входить в систему.

Что такое API управления учетными данными?

API управления учетными данными позволяет разработчикам хранить и извлекать учетные данные паролей и федеративные учетные данные и предоставляет 3 функции:

  • navigator.credentials.get()
  • navigator.credentials.store()
  • navigator.credentials.requireUserMediation()

Используя эти простые API, разработчики могут делать такие мощные вещи, как:

  • Предоставьте пользователям возможность входить в систему одним касанием.
  • Запомните федеративную учетную запись, которую пользователь использовал для входа.
  • Выполните повторный вход пользователей по истечении срока действия сеанса.

В реализации Chrome учетные данные будут храниться в менеджере паролей Chrome. Если пользователи вошли в Chrome, они могут синхронизировать пароли пользователей на разных устройствах. Эти синхронизированные пароли также можно использовать совместно с приложениями Android, которые интегрировали API Smart Lock for Passwords для Android для обеспечения беспрепятственной кросс-платформенной работы .

Интеграция API управления учетными данными с вашим сайтом

Способ использования API управления учетными данными на вашем веб-сайте может различаться в зависимости от его архитектуры. Это одностраничное приложение? Это устаревшая архитектура с переходами страниц? Форма входа находится только на верхней странице? Кнопки входа расположены повсюду? Могут ли пользователи полноценно просматривать ваш сайт, не входя в систему? Работает ли федерация во всплывающих окнах? Или это требует взаимодействия на нескольких страницах?

Практически невозможно охватить все эти случаи, но давайте взглянем на типичное одностраничное приложение.

  • Верхняя страница представляет собой форму регистрации.
  • Нажав кнопку «Войти», пользователи перейдут к форме входа.
  • И форма регистрации, и форма входа имеют типичные варианты учетных данных с идентификатором/паролем и федерации, например, с помощью входа в Google и входа в Facebook.

Используя API управления учетными данными, вы сможете добавить на сайт следующие функции, например:

  • Показывать средство выбора учетной записи при входе в систему: показывает собственный пользовательский интерфейс выбора учетной записи, когда пользователь нажимает «Войти».
  • Сохраните учетные данные: после успешного входа предложите сохранить учетные данные в диспетчере паролей браузера для дальнейшего использования.
  • Разрешить пользователю автоматически выполнить повторный вход. Разрешить пользователю выполнить повторный вход, если срок сеанса истек.
  • Посреднический автоматический вход: как только пользователь выйдет из системы, отключите автоматический вход для следующего посещения пользователя.

Вы можете испытать эти функции, реализованные на демонстрационном сайте с примером кода .

Показывать средство выбора учетной записи при входе в систему

Между нажатием пользователем кнопки «Войти» и переходом к форме входа вы можете использовать navigator.credentials.get() для получения учетных данных. Chrome отобразит пользовательский интерфейс выбора учетной записи, из которого пользователь может выбрать учетную запись.

Появится пользовательский интерфейс выбора учетной записи, позволяющий пользователю выбрать учетную запись для входа.
Всплывает пользовательский интерфейс выбора учетной записи, позволяющий пользователю выбрать учетную запись для входа в систему.

Получение объекта учетных данных пароля

Чтобы отобразить учетные данные пароля в качестве параметров учетной записи, используйте password: true .

navigator.credentials.get({
    password: true, // `true` to obtain password credentials
}).then(function(cred) {
    // continuation
    ...

Использование пароля для входа в систему

Как только пользователь выберет учетную запись, функция разрешения получит учетные данные пароля. Вы можете отправить его на сервер с помощью 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

Использование федеративных учетных данных для входа в систему

Чтобы показать пользователю объединенные учетные записи, добавьте в параметры get() federated , который принимает массив поставщиков удостоверений.

Когда в менеджере паролей хранится несколько учетных записей.
Когда в менеджере паролей хранится несколько учетных записей
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
    ...

Вы можете проверить свойство type объекта учетных данных, чтобы определить, является ли он PasswordCredential ( type == 'password' ) или FederatedCredential ( type == 'federated' ). Если учетными данными является FederatedCredential , вы можете вызвать соответствующий API, используя содержащуюся в нем информацию.

    });
} 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
Блок-схема управления учетными данными.

Учетные данные магазина

Когда пользователь входит на ваш сайт с помощью формы, вы можете использовать navigator.credentials.store() для хранения учетных данных. Пользователю будет предложено сохранить его или нет. В зависимости от типа учетных данных используйте new PasswordCredential() или new FederatedCredential() чтобы создать объект учетных данных, который вы хотите сохранить.

Chrome спрашивает пользователей, хотят ли они сохранить учетные данные (или поставщика федерации).
Chrome спрашивает пользователей, хотят ли они сохранить учетные данные (или поставщика федерации).

Создание и сохранение учетных данных пароля из элемента формы

В следующем коде используются атрибуты autocomplete для автоматического сопоставления элементов формы с параметрами объекта PasswordCredential .

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
});

Создание и хранение федеративных учетных данных

// 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
});
Войдите в блок-схему.

Разрешить пользователю автоматически войти в систему

Когда пользователь покидает ваш сайт и возвращается позже, возможно, срок сеанса истек. Не заставляйте пользователя вводить пароль каждый раз, когда он возвращается. Позвольте пользователю автоматически войти в систему.

Когда пользователь автоматически войдет в систему, появится всплывающее уведомление.
Когда пользователь автоматически войдет в систему, появится всплывающее уведомление.

Получение объекта учетных данных

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

Код должен выглядеть примерно так, как вы видели в разделе «Показывать средство выбора учетной записи при входе в систему». Единственное отличие состоит в том, что вы установите unmediated: true .

Это немедленно разрешает функцию и дает вам учетные данные для автоматического входа пользователя в систему. Существует несколько условий:

  • Пользователь тепло приветствовал функцию автоматического входа.
  • Пользователь ранее вошел на веб-сайт с помощью API управления учетными данными.
  • У пользователя сохранены только одни учетные данные для вашего происхождения.
  • Пользователь не вышел из системы явным образом в предыдущем сеансе.

Если какое-либо из этих условий не выполнено, функция будет отклонена.

Схема потока объекта учетных данных

Посредничество автоматического входа в систему

Когда пользователь выходит из вашего веб-сайта, вы несете ответственность за то, чтобы он не выполнил автоматический вход снова . Чтобы обеспечить это, API управления учетными данными предоставляет механизм, называемый посредничеством . Вы можете включить режим посредничества, вызвав navigator.credentials.requireUserMediation() . Пока статус посредничества пользователя для источника включен с использованием unmediated: true с navigator.credentials.get() , эта функция будет разрешаться с undefined .

Посредничество автоматического входа в систему

navigator.credentials.requireUserMediation();
Схема автоматического входа в систему.

Часто задаваемые вопросы

Может ли JavaScript на веб-сайте получить необработанный пароль? Нет. Вы можете получить пароли только как часть PasswordCredential и их нельзя раскрыть каким-либо образом.

Можно ли сохранить 3 набора цифр для идентификатора с помощью API управления учетными данными? Не сейчас. Ваше мнение о спецификации будет высоко оценено.

Могу ли я использовать API управления учетными данными внутри iframe? API ограничен контекстами верхнего уровня. Вызовы .get() или .store() в iframe будут решены немедленно и безрезультатно.

Могу ли я интегрировать расширение Chrome для управления паролями с API управления учетными данными? Вы можете переопределить navigator.credentials и подключить его к своему расширению Chrome для get() или store() .

Ресурсы

Чтобы узнать больше об API управления учетными данными, ознакомьтесь с Руководством по интеграции .