使用凭据管理 API 简化登录流程

要提供成熟的用户体验,请务必帮助用户 验证他们自己的身份通过身份验证的用户可以与 可以使用专用个人资料互相同步、在设备间同步数据或处理数据 离线访问;这个列表还在不断增加但无论是创建、记忆和输入, 对最终用户而言,密码往往非常麻烦,尤其是在移动设备屏幕上 这会导致他们在不同的网站上重复使用相同的密码。当然 存在安全风险

最新版本的 Chrome (51) 支持 Credential Management API。这是一个 标准轨道提案,让开发者能够以编程方式访问 浏览器的凭据管理器,可帮助用户更轻松地登录。

什么是 Credential Management API?

借助 Credential Management API,开发者可以存储和检索密码 凭据和联合凭据,并提供 3 个功能:

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

通过使用这些简单的 API,开发者可以实现诸多强大功能,例如:

  • 让用户能够一键登录。
  • 记住用户用于登录的联合账号。
  • 会话过期后,让用户重新登录。

在 Chrome 的实现代码中,凭据将存储在 Chrome 的密码中 。如果用户已登录 Chrome,则可以同步用户的密码 跨设备访问。这些已同步的密码也可以分享给 Android 应用 该 API 集成了 Android 版 Smart Lock for Passwords API 打造顺畅的跨平台体验

将 Credential Management API 与您的网站集成

在网站上使用 Credential Management API 的方式可能会有所不同 具体取决于其架构是单页应用吗?是否属于旧版 页面转换架构?登录表单是否仅位于顶部 页面?登录按钮是否在所有位置?用户能否有效浏览您的 而不登录网站?联合可以在弹出窗口中运行吗?还是这样 需要跨多个网页互动?

我们几乎不可能涵盖所有这些情况 典型的单页应用

  • 页面顶部是注册表单。
  • 通过点按“登录”按钮,用户将导航到一个登录表单。
  • 注册表单和登录表单都具有典型的 ID/密码选项 凭据和联合,如。

通过使用 Credential Management API,您将能够添加以下内容 功能,例如:

  • 在登录时显示账号选择器:显示原生账号选择器界面 当用户点按“登录”时触发。
  • 存储凭据:在成功登录后,询问是否存储 将凭据信息传送给浏览器的密码管理器,以供日后使用。
  • 允许用户自动重新登录:让用户重新登录: 会话已过期。
  • 中介自动登录:在用户退出账号后,为以下账号停用自动登录: 用户的下一次访问

您可以通过演示网站及其示例代码体验这些功能。

登录时显示账号选择器

用户点按“登录”之后按钮和导航到登录表单,您就可以 可以使用 navigator.credentials.get() 来获取凭据信息。Chrome 会显示一个账号选择器界面,您可通过该界面 用户可以选择账号

<ph type="x-smartling-placeholder">
</ph> 系统会弹出账号选择器界面,供用户选择要登录的账号。
系统会弹出账号选择器界面,供用户选择要登录的账号

获取密码凭据对象

若要将密码凭据显示为账号选项,请使用 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() 选项。

<ph type="x-smartling-placeholder">
</ph> 当密码管理工具中存储了多个账号时。 <ph type="x-smartling-placeholder">
</ph> 当密码管理器中存储了多个账号时
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() 创建您要存储的凭据对象。

<ph type="x-smartling-placeholder">
</ph> Chrome 会询问用户是否要存储该凭据(或联合提供方)。 <ph type="x-smartling-placeholder">
</ph> 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
});
登录流程图。

让用户自动重新登录

当用户离开您的网站稍后又回来时, 会话已过期。不要让用户每次都重新输入密码 返回。让用户自动重新登录。

<ph type="x-smartling-placeholder">
</ph> 当用户自动登录时,系统会弹出一条通知。 <ph type="x-smartling-placeholder">
</ph> 当用户自动登录时,系统会弹出一条通知。

获取凭据对象

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
    ...
    }
});

该代码应与您在“显示账号选择器”页面中看到的代码类似, 登录时”部分。唯一的区别在于 unmediated: true

这样会立即解析该函数,并为您提供用于 自动登录用户下面是一些条件:

  • 用户已表示欢迎,欢迎使用自动登录功能。
  • 用户之前已使用 Credential Management API 登录网站。
  • 用户只为您的源存储了一个凭据。
  • 用户在上一个会话中未明确退出登录。

如果这些条件中有任何一个不满足,该函数就会被拒绝。

凭据对象流程图

中介自动登录

当用户退出您的网站时,您有责任确保 用户不会自动重新登录。为确保 因此,Credential Management API 提供了一种称为中介的机制。 您可以通过以下方式启用中介模式: navigator.credentials.requireUserMediation()。 只要用户针对该源的中介状态处于启用状态,使用 将 unmediated: true 替换为 navigator.credentials.get(),该函数将 请使用 undefined 解析。

通过中介功能自动登录

navigator.credentials.requireUserMediation();
自动登录流程图。

常见问题解答

网站上的 JavaScript 能否检索原始网页的 密码? 不可以。您只能通过 PasswordCredential 来获取密码, 任何形式的信息

可以使用凭据存储 3 组数字作为 ID 吗 Management API? 暂不支持。我们会将您对本规范的反馈 非常感谢。

我可以在 iframe 内使用 Credential Management API 吗? 该 API 仅限于顶级上下文。拨打 .get().store() 的电话 会立即解析而无效。

我可以将密码管理 Chrome 扩展程序与凭据集成吗 Management API? 您可以替换 navigator.credentials 并将其挂接到您的 Chrome 扩展程序, get()store() 凭据。

资源

如需详细了解 Credential Management API,请参阅集成指南