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

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

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

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

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

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

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

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

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

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

Чтобы показать пользователю федеративные учетные записи, добавьте federated , который принимает массив поставщиков удостоверений, к параметрам 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
    ...

Вы можете проверить свойство 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 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
    ...
    }
});

Код должен выглядеть примерно так же, как вы видели в разделе «Показывать Account Chooser при входе в систему». Единственное отличие в том, что вы установите 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 управления учетными данными, ознакомьтесь с Руководством по интеграции .