Para oferecer uma experiência do usuário sofisticada, é importante ajudar os usuários a se autenticarem no seu site. Os usuários autenticados podem interagir entre si usando um perfil dedicado, sincronizar dados entre dispositivos ou processar dados off-line. A lista não acaba. No entanto, criar, lembrar e digitar senhas costuma ser complicado para os usuários finais, principalmente nas telas de dispositivos móveis, o que os leva a reutilizar as mesmas senhas em sites diferentes. Claro, esse é um risco para a segurança.
A versão mais recente do Chrome (51) é compatível com a API Credential Management. É uma proposta padrão no W3C que oferece aos desenvolvedores acesso programático ao gerenciador de credenciais de um navegador e ajuda os usuários a fazer login com mais facilidade.
O que é a API Credential Management?
A API Credential Management permite que os desenvolvedores armazenem e recuperem credenciais de senha e credenciais federadas e oferece três funções:
navigator.credentials.get()
navigator.credentials.store()
navigator.credentials.requireUserMediation()
Com essas APIs simples, os desenvolvedores podem fazer coisas poderosas, como:
- Permita que os usuários façam login com apenas um toque.
- Lembre-se da conta federada que o usuário usou para fazer login.
- Faça o login dos usuários novamente quando uma sessão expirar.
Na implementação do Chrome, as credenciais serão armazenadas no gerenciador de senhas do navegador. Se os usuários fizerem login no Chrome, eles poderão sincronizar as senhas em vários dispositivos. Essas senhas sincronizadas também podem ser compartilhadas com apps Android que têm a API Smart Lock for Passwords para Android integrada para uma experiência multiplataforma integrada.
Integrar a API Credential Management ao site
A maneira como você usa a API Credential Management com seu site pode variar dependendo da arquitetura dela. É um app de página única? É uma arquitetura legada com transições de página? O formulário de login está localizado apenas na parte de cima da página? Os botões de login estão em todos os lugares? Os usuários conseguem navegar significativamente pelo site sem fazer login? A federação funciona em janelas pop-up? Ou é necessário interagir em várias páginas?
É quase impossível cobrir todos esses casos, mas vamos conferir um app típico de página única.
- A página superior é um formulário de inscrição.
- Ao tocar no botão "Fazer login", os usuários acessam um formulário de login.
- Os formulários de registro e login têm as opções típicas de credenciais de ID/senha e federação, por exemplo, com o Login do Google e do Facebook.
Ao usar a API Credential Management, será possível adicionar os seguintes recursos ao site, por exemplo:
- Mostrar um seletor de conta ao fazer login:mostra uma interface nativa do seletor de conta quando um usuário toca em "Fazer login".
- Armazenar credenciais:após o login bem-sucedido, ofereça a opção de armazenar as informações da credencial no gerenciador de senhas do navegador para uso posterior.
- Permitir que o usuário faça login de novo automaticamente:permita que o usuário faça login novamente se uma sessão tiver expirado.
- Mediar login automático:depois que um usuário sair, desative o login automático para a próxima visita dele.
Confira esses recursos implementados em um site de demonstração com o exemplo de código.
Mostrar o Seletor de conta ao fazer login
Entre um toque do usuário no botão "Fazer login" e a navegação até um formulário de login, você pode usar navigator.credentials.get() para ver informações das credenciais. O Chrome mostrará uma interface de seleção de conta na qual o usuário pode escolher uma conta.
![Uma interface do seletor de conta aparece para que o usuário selecione uma conta para fazer login.](https://developer.chrome.com/static/blog/credential-management-api/image/an-account-chooser-ui-pop-a9dd3159618c6.png?authuser=6&hl=pt)
Como receber um objeto de credencial de senha
Para mostrar credenciais de senha como opções de conta, use password: true
.
navigator.credentials.get({
password: true, // `true` to obtain password credentials
}).then(function(cred) {
// continuation
...
Como usar uma credencial de senha para fazer login
Depois que o usuário fizer uma seleção de conta, a função de resolução receberá uma
credencial de senha. É possível enviá-lo ao servidor usando 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
Como usar uma credencial federada para fazer login
Para mostrar contas federadas a um usuário, adicione federated
, que usa uma matriz
de provedores de identidade, às opções get()
.
![Quando várias contas são armazenadas no gerenciador de senhas.](https://developer.chrome.com/static/blog/credential-management-api/image/when-multiple-accounts-ar-a47c9e7a48cd8.png?authuser=6&hl=pt)
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
...
Você pode examinar a propriedade type
do objeto de credencial para ver se é PasswordCredential
(type == 'password'
) ou FederatedCredential
(type == 'federated'
).
Se a credencial for um
FederatedCredential
,
você poderá chamar a API apropriada usando as informações que ela contém.
});
} 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
![Fluxograma de gerenciamento de credenciais.](https://developer.chrome.com/static/blog/credential-management-api/image/credentials-managemente-f-fa888851aa7eb.png?authuser=6&hl=pt)
Armazenar credenciais
Quando um usuário faz login no seu site usando um formulário, você pode usar navigator.credentials.store() para armazenar a credencial. O usuário receberá uma solicitação para armazená-la ou não. Dependendo
do tipo da credencial, use new
PasswordCredential()
ou new
FederatedCredential()
para criar um objeto de credencial que você queira armazenar.
![O Chrome pergunta aos usuários se eles querem armazenar a credencial (ou um provedor de federação).](https://developer.chrome.com/static/blog/credential-management-api/image/chrome-asks-users-they-737adba9a868a.png?authuser=6&hl=pt)
Como criar e armazenar uma credencial de senha de um elemento de formulário
O código a seguir usa atributos autocomplete
para mapear
automaticamente os elementos do formulário para os parâmetros do objeto
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
});
Como criar e armazenar uma credencial federada
// 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
});
![Diagrama de fluxo de login.](https://developer.chrome.com/static/blog/credential-management-api/image/sign-flow-diagram-71ec10662a836.png?authuser=6&hl=pt)
Permitir que o usuário faça login de novo automaticamente
Quando um usuário sai do seu site e volta mais tarde, é possível que a sessão tenha expirado. Não incomode o usuário a digitar a senha sempre que voltar. Permita que o usuário faça login de novo automaticamente.
![Quando um usuário é conectado automaticamente, uma notificação aparece.](https://developer.chrome.com/static/blog/credential-management-api/image/when-user-is-automatical-dc29fbf63e6c4.png?authuser=6&hl=pt)
Como receber um objeto de credencial
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
...
}
});
O código será semelhante ao exibido na seção "Mostrar seletor de conta
ao fazer login". A única diferença é que você definirá unmediated: true
.
Isso resolve a função imediatamente e fornece a credencial para fazer o login do usuário automaticamente. Existem algumas condições:
- O usuário reconheceu o recurso de login automático em uma recepção calorosa.
- O usuário já fez login no site com a API Credential Management.
- O usuário tem apenas uma credencial armazenada para sua origem.
- O usuário não saiu da sessão explicitamente na sessão anterior.
Se alguma dessas condições não for atendida, a função será rejeitada.
![Diagrama de fluxo de objeto de credencial](https://developer.chrome.com/static/blog/credential-management-api/image/credential-object-flow-di-e5c6caa13d1cd.png?authuser=6&hl=pt)
Mediar login automático
Quando um usuário sai do seu site, é sua responsabilidade garantir
que ele não faça login de novo automaticamente. Para garantir
isso, a API Credential Management oferece um mecanismo chamado mediação.
É possível ativar o modo de mediação chamando
navigator.credentials.requireUserMediation()
.
Contanto que o status de mediação do usuário para a origem esteja ativado, usando
unmediated: true
com navigator.credentials.get()
, essa função será
resolvida com undefined
.
Como mediar o login automático
navigator.credentials.requireUserMediation();
![Fluxograma de login automático.](https://developer.chrome.com/static/blog/credential-management-api/image/auto-sign-flow-chart-4a8bd010949ff.png?authuser=6&hl=pt)
Perguntas frequentes
É possível que o JavaScript no site recupere uma senha
bruta?
Não. As senhas só podem ser extraídas como parte do PasswordCredential
, e elas não são
expansíveis de nenhuma forma.
É possível armazenar três conjuntos de dígitos para um ID usando a API Credential Management? No momento, não. É um prazer receber seu feedback sobre a especificação.
Posso usar a API Credential Management em um iframe?
A API é restrita a contextos de nível superior. As chamadas para .get()
ou .store()
em um iframe serão resolvidas imediatamente sem efeito.
Posso integrar minha extensão do Chrome de gerenciamento de senhas à API
Credential Management?
Você pode substituir navigator.credentials
e vinculá-lo à sua extensão do Chrome às credenciais get()
ou store()
.
Recursos
Para saber mais sobre a API Credential Management, confira o Guia de integração.