Mantenha seus formulários de registro e login o mais simples possível.
Salvar credenciais dos formulários de login para que os usuários não precisem fazer login novamente quando retornarem.
Para armazenar credenciais de usuário de formulários:
- Inclua
autocomplete
no formulário. - Impeça o envio do formulário.
- Envie uma solicitação para a autenticação.
- Armazene a credencial.
- Atualize a interface ou prossiga para a página personalizada.
Inclua autocomplete
no formulário
Antes de continuar,
verifique se o formulário inclui atributos autocomplete
.
Isso ajuda a API Credential Management a encontrar o id
e o password
.
do formulário e construa um objeto de credencial.
Isso também ajuda os navegadores sem suporte à API Credential Management. para entender a semântica dele. Saiba mais sobre o preenchimento automático em este artigo de Jason Grigsby (em inglês).
<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>
Impedir o envio do formulário
Quando o usuário pressionar o botão "Enviar", impeça o envio do formulário, o que poderia causar resultam em uma transição de página:
var f = document.querySelector('#signup');
f.addEventListener('submit', e => {
e.preventDefault();
Ao impedir uma transição de página, é possível reter as informações da credencial enquanto verifica a autenticidade.
Autenticar enviando uma solicitação
Para autenticar o usuário, envie informações de credenciais para seu servidor usando AJAX.
No lado do servidor, crie um endpoint (ou simplesmente altere um endpoint existente) que responda com o código HTTP 200 ou 401, de modo que fique claro para o navegador se a inscrição/login/alteração de senha foi bem-sucedida ou não.
Exemplo:
// Try sign-in with AJAX
fetch('/signin', {
method: 'POST',
body: new FormData(e.target),
credentials: 'include',
});
Armazenar a credencial
Para armazenar uma credencial, primeiro confira se a API está disponível
e instanciar um
PasswordCredential
com o elemento de formulário como argumento
de forma síncrona ou assíncrona.
Chame
navigator.credentials.store()
.
Se a API não estiver disponível,
basta encaminhar as informações do perfil para a próxima etapa.
Exemplo síncrono:
if (window.PasswordCredential) {
var c = new PasswordCredential(e.target);
return navigator.credentials.store(c);
} else {
return Promise.resolve(profile);
}
Exemplo assíncrono:
if (window.PasswordCredential) {
var c = await navigator.credentials.create({password: e.target});
return navigator.credentials.store(c);
} else {
return Promise.resolve(profile);
}
Quando a solicitação for bem-sucedida, armazene as informações da credencial. Não armazene as informações de credenciais se a solicitação falhar porque isso pode confundir os usuários recorrentes.
Quando o navegador Chrome recebe informações de credenciais, aparece uma notificação pedindo para armazenar uma credencial (ou provedor de federação).
![repositório de credenciais](https://web.developers.google.cn/static/articles/security-credential-management-save-forms/image/store-credential-f27fdeafeab5c.png?authuser=5&hl=pt)
Atualizar a interface
Se tudo tiver dado certo, atualize a interface usando as informações do perfil, ou prosseguir para a página personalizada.
}).then(profile => {
if (profile) {
updateUI(profile);
}
}).catch(error => {
showError('Sign-in Failed');
});
});
Exemplo de código completo
// 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');
});
});
Compatibilidade com navegadores
PasswordCredential
navigator.credentials.store()