要让用户登录,请从浏览器密码中检索凭据 并将其用于自动登录用户。 对于拥有多个账号的用户, 让他们使用账号选择器一键选择账号。
自动登录
您可以在网站上的任何位置自动登录; 不仅包括首页,还包括其他叶级页。 当用户访问您网站上的不同网页时,这种匹配类型非常有用。 。
如需启用自动登录,请执行以下操作:
- 获取凭据信息。
- 对用户进行身份验证。
- 更新界面或前往个性化页面。
获取凭据信息
要获取凭据信息,请调用
navigator.credentials.get()
。
指定要请求的凭据类型
方法是为其指定 password
或 federated
。
始终使用mediation: 'silent'
进行自动登录,
因此,您可以在用户执行下列操作时轻松关闭该流程:
- 未存储任何凭据。
- 存储了多个凭据。
- 已退出账号。
在获取凭据之前 别忘了检查用户是否已登录:
if (window.PasswordCredential || window.FederatedCredential) {
if (!user.isSignedIn()) {
navigator.credentials.get({
password: true,
federated: {
providers: ['https://accounts.google.com'],
},
mediation: 'silent',
});
// ...
}
}
navigator.credentials.get()
返回的 promise 将解析
凭据对象或 null
。
如需确定是 PasswordCredential
还是 FederatedCredential
,
只需查看对象的 .type
属性,
其值为 password
或 federated
。
如果 .type
为 federated
,
.provider
属性是一个表示身份提供方的字符串。
对用户进行身份验证
获得凭据后
根据凭据类型运行身份验证流程,
password
或 federated
:
}).then(c => {
if (c) {
switch (c.type) {
case 'password':
return sendRequest(c);
break;
case 'federated':
return gSignIn(c);
break;
}
} else {
return Promise.resolve();
}
当 promise 进行解析时, 检查是否收到了凭据对象。 如果不能,则表示无法自动登录。 静默关闭自动登录流程。
更新界面
如果身份验证成功 更新界面或将用户转到个性化页面:
}).then(profile => {
if (profile) {
updateUI(profile);
}
别忘了显示身份验证错误消息
为了避免用户混淆 用户应该会看到显示“正在登录”的蓝色消息框 在获取凭据对象时触发:
![显示用户正在登录的蓝色消息框。](https://web.developers.google.cn/static/articles/security-credential-management-retrieve-credentials/image/blue-toast-showing-user-i-434a344bb78b3.png?authuser=8&hl=sr)
重要提示:如果您成功获取了凭据对象 但无法验证用户身份,则应显示错误消息:
}).catch(error => {
showError('Sign-in Failed');
});
}
}
完整代码示例
if (window.PasswordCredential || window.FederatedCredential) {
if (!user.isSignedIn()) {
navigator.credentials
.get({
password: true,
federated: {
providers: ['https://accounts.google.com'],
},
mediation: 'silent',
})
.then((c) => {
if (c) {
switch (c.type) {
case 'password':
return sendRequest(c);
break;
case 'federated':
return gSignIn(c);
break;
}
} else {
return Promise.resolve();
}
})
.then((profile) => {
if (profile) {
updateUI(profile);
}
})
.catch((error) => {
showError('Sign-in Failed');
});
}
}
通过账号选择器登录
如果用户需要使用中介,或者有多个账号, 使用账号选择器让用户登录 而跳过普通的登录表单,例如:
![显示多个账号的 Google 账号选择器。](https://web.developers.google.cn/static/articles/security-credential-management-retrieve-credentials/image/google-account-chooser-sh-76222c6b4a3fb.png?authuser=8&hl=sr)
通过账号选择器登录的步骤与 自动登录、 另一个调用,以显示账号选择器 来获取凭据信息:
- 获取凭据信息并显示账号选择器。
- 对用户进行身份验证。
- 更新界面或前往个性化页面。
获取凭据信息并显示账号选择器
为响应指定的用户操作显示账号选择器;
例如,当用户点按“登录”时按钮。致电
navigator.credentials.get()
,
并添加 mediation: 'optional'
或 mediation: 'required'
以显示账号选择器。
如果 mediation
为 required
,系统会始终向用户显示用于登录的账号选择器。
通过此选项,具有多个账号的用户可在账号间轻松切换。
当 mediation
为 optional
时,
在用户登录后,系统会明确向用户显示
navigator.credentials.preventSilentAccess()
调用。
这通常是为了确保系统不会自动登录
在用户选择退出或取消注册后触发。
显示 mediation: 'optional'
的示例:
var signin = document.querySelector('#signin');
signin.addEventListener('click', e => {
if (window.PasswordCredential || window.FederatedCredential) {
navigator.credentials.get({
password: true,
federated: {
providers: [
'https://accounts.google.com'
]
},
mediation: 'optional'
}).then(c => {
用户选择账号后
promise 使用凭据进行解析。
如果用户取消了账号选择器,
或者没有存储凭据
promise 使用 null
进行解析。
在这种情况下,请回退到登录表单体验。
别忘了返回登录表单
如果遇到以下任一情况,您应回退到登录表单:
- 未存储任何凭据。
- 用户关闭了账号选择器,未选择账号。
- 此 API 不可用。
}).then(profile => {
if (profile) {
updateUI(profile);
} else {
location.href = '/signin';
}
}).catch(error => {
location.href = '/signin';
});
完整代码示例
var signin = document.querySelector('#signin');
signin.addEventListener('click', (e) => {
if (window.PasswordCredential || window.FederatedCredential) {
navigator.credentials
.get({
password: true,
federated: {
providers: ['https://accounts.google.com'],
},
mediation: 'optional',
})
.then((c) => {
if (c) {
switch (c.type) {
case 'password':
return sendRequest(c);
break;
case 'federated':
return gSignIn(c);
break;
}
} else {
return Promise.resolve();
}
})
.then((profile) => {
if (profile) {
updateUI(profile);
} else {
location.href = '/signin';
}
})
.catch((error) => {
location.href = '/signin';
});
}
});
联合登录
借助联合登录,用户只需点按一下即可登录, 而无需记住您网站的其他登录详细信息。
如需实现联合登录,请执行以下操作:
- 使用第三方身份对用户进行身份验证。
- 存储身份信息。
- 更新界面或进入个性化页面(与自动登录相同)。
使用第三方身份对用户进行身份验证
当用户点按联合登录按钮时
使用
FederatedCredential
。
例如,如果提供商是 Google,则使用 Google 登录 JavaScript 库:
navigator.credentials
.get({
password: true,
mediation: 'optional',
federated: {
providers: ['https://account.google.com'],
},
})
.then(function (cred) {
if (cred) {
// Instantiate an auth object
var auth2 = gapi.auth2.getAuthInstance();
// Is this user already signed in?
if (auth2.isSignedIn.get()) {
var googleUser = auth2.currentUser.get();
// Same user as in the credential object?
if (googleUser.getBasicProfile().getEmail() === cred.id) {
// Continue with the signed-in user.
return Promise.resolve(googleUser);
}
}
// Otherwise, run a new authentication flow.
return auth2.signIn({
login_hint: id || '',
});
}
});
Google 登录会生成 ID 令牌作为身份验证的证明。
通常,联合登录建立在标准协议之上,例如 OpenID Connect 或 OAuth。 如需了解如何使用联合账号进行身份验证, 指的是各自的联合身份提供方文档。 热门示例包括:
存储身份信息
完成身份验证后,您可以存储身份信息。
您要在此处存储的信息是身份提供方提供的id
以及表示身份提供方的提供方字符串
(name
和 iconURL
是可选的)。
有关详情,请参阅
凭据管理规范。
如需存储联合账号详情,请实例化一个新的
FederatedCredential
对象包含用户的标识符和提供商的标识符。
然后调用
navigator.credentials.store()
存储身份信息。
联合成功后
同步或异步实例化 FederatedCredential
:
同步方法示例:
// Create credential object synchronously.
var cred = new FederatedCredential({
id: id, // id in IdP
provider: 'https://account.google.com', // A string representing IdP
name: name, // name in IdP
iconURL: iconUrl, // Profile image url
});
异步方法示例:
// Create credential object asynchronously.
var cred = await navigator.credentials.create({
federated: {
id: id,
provider: 'https://accounts.google.com',
name: name,
iconURL: iconUrl,
},
});
然后存储凭据对象:
// Store it
navigator.credentials.store(cred).then(function () {
// continuation
});
退出账号
点按“退出”按钮后,让您的用户退出登录。 首先终止会话 然后关闭自动登录功能,以便将来访问。 (如何终止会话完全由您决定。)
关闭自动登录功能,方便日后访问
致电
navigator.credentials.preventSilentAccess()
:
signoutUser();
if (navigator.credentials && navigator.credentials.preventSilentAccess) {
navigator.credentials.preventSilentAccess();
}
这样可以确保用户下次启用自动登录功能时,系统就不会自动登录。 如需恢复自动登录,用户可以选择刻意登录 只需从账号选择器中选择想要登录的账号即可。 然后,在他们明确退出之前,用户始终会重新登录。