Формы регистрации и входа должны быть максимально простыми.
Сохраняйте учетные данные из форм входа, чтобы пользователям не приходилось вводить их повторно.
Чтобы сохранять учетные данные пользователей из форм:
- Добавьте в форму
autocomplete. - Запретить отправку формы.
- Выполните аутентификацию, отправив запрос.
- Сохраните учетные данные.
- Обновите интерфейс или перейдите на персонализированную страницу.
Добавить в форму autocomplete
Прежде чем продолжить, проверьте, есть ли в вашей форме атрибуты autocomplete.
Это помогает Credential Management API найти id и password в форме и создать объект учетных данных.
Это также помогает браузерам, не поддерживающим Credential Management API, понять его семантику. Подробнее об автозаполнении читайте в этой статье Джейсона Григсби (Jason Grigsby).
<form id="signup" method="post">
<input name="email" type="text" autocomplete="username email" />
<input name="display-name" type="text" autocomplete="name" />
<input name="password" type="password" autocomplete="new-password" />
<input type="submit" value="Sign Up!" />
</form>
Запретить отправку формы
Когда пользователь нажимает кнопку отправки, предотвратите отправку формы, которая в противном случае приведет к переходу на другую страницу:
var f = document.querySelector('#signup');
f.addEventListener('submit', e => {
e.preventDefault();
Предотвращая переход на другую страницу, вы можете сохранить учетные данные, пока проверяете их подлинность.
Выполнить аутентификацию, отправив запрос
Чтобы выполнить аутентификацию пользователя, передайте учетные данные на сервер с помощью AJAX.
На стороне сервера создайте конечную точку (или измените существующую), которая отвечает кодом HTTP 200 или 401, чтобы браузеру было понятно, успешно ли выполнена регистрация, вход или смена пароля.
Пример:
// Try sign-in with AJAX
fetch('/signin', {
method: 'POST',
body: new FormData(e.target),
credentials: 'include',
});
Сохранение учетных данных
Чтобы сохранить учетные данные, сначала проверьте, доступен ли API, а затем создайте экземпляр PasswordCredential с элементом формы в качестве аргумента (синхронно или асинхронно).
Позвоните по номеру
navigator.credentials.store().
Если API недоступен, вы можете просто передать информацию профиля на следующий шаг.
Пример синхронного запроса:
if (window.PasswordCredential) {
var c = new PasswordCredential(e.target);
return navigator.credentials.store(c);
} else {
return Promise.resolve(profile);
}
Пример асинхронного тега:
if (window.PasswordCredential) {
var c = await navigator.credentials.create({password: e.target});
return navigator.credentials.store(c);
} else {
return Promise.resolve(profile);
}
Если запрос выполнен успешно, сохраните учетные данные. Не сохраняйте учетные данные, если запрос не выполнен, так как это может запутать вернувшихся пользователей.
Когда браузер Chrome получает учетные данные, появляется уведомление с предложением сохранить их (или поставщика федеративной идентификации).
Обновление интерфейса
Если все прошло успешно, обновите интерфейс, используя информацию профиля, или перейдите на персонализированную страницу.
}).then(profile => {
if (profile) {
updateUI(profile);
}
}).catch(error => {
showError('Sign-in Failed');
});
});
Полный пример кода
// Get form's DOM object
var f = document.querySelector('#signup');
f.addEventListener('submit', (e) => {
// Stop submitting form by itself
e.preventDefault();
// Try sign-in with AJAX
fetch('/signin', {
method: 'POST',
body: new FormData(e.target),
credentials: 'include',
})
.then((res) => {
if (res.status == 200) {
return Promise.resolve();
} else {
return Promise.reject('Sign-in failed');
}
})
.then((profile) => {
// Instantiate PasswordCredential with the form
if (window.PasswordCredential) {
var c = new PasswordCredential(e.target);
return navigator.credentials.store(c);
} else {
return Promise.resolve(profile);
}
})
.then((profile) => {
// Successful sign-in
if (profile) {
updateUI(profile);
}
})
.catch((error) => {
// Sign-in failed
showError('Sign-in Failed');
});
});
Совместимость браузеров
PasswordCredential
navigator.credentials.store()