Credential Management API 的最新动态

Google I/O 大会专题演讲会介绍本文所述的一些更新, 安全、无缝的登录:持续吸引用户互动

Chrome 57

Chrome 57 为 Credential Management API

可通过其他子网域共享凭据

现在,Chrome 可以使用 Credential Management API。 例如,如果密码存储在 login.example.com 中, www.example.com 上的脚本可以在账号选择器对话框中将其显示为账号项之一。

您必须使用 navigator.credentials.store() 明确存储密码, 这样,当用户通过点击对话框选择凭据时, 系统会传递该密码并将其复制到当前源。

存储后,密码就可以作为凭据使用 在同一源 www.example.com 之后。

在下面的屏幕截图中,存储在 login.aliexpress.com 下的凭据信息 对 m.aliexpress.com 可见,并可供用户选择:

<ph type="x-smartling-placeholder">
</ph> 显示所选子网域登录详细信息的账号选择器

Chrome 60

Chrome 60 针对 Credential Management API

特征检测需要注意

查看用于访问基于密码和 联合凭据是否可用,请检查 window.PasswordCredentialwindow.FederatedCredential 可用。

if (window.PasswordCredential || window.FederatedCredential) {
  // The Credential Management API is available
}

PasswordCredential 对象现在包含密码

Credential Management API 采用保守的方法处理密码。 它从 JavaScript 中隐藏密码,这需要开发者 将 PasswordCredential 对象直接发送到其服务器 ,通过 fetch() API 的扩展进行验证。

但是,这种方法带来了许多限制。 我们已收到反馈,指出开发者无法使用该 API,原因如下:

  • 他们必须将密码作为 JSON 对象的一部分进行发送。

  • 他们必须将密码的哈希值发送至服务器。

在执行安全分析并确定隐藏密码后 无法像我们希望的那样有效地阻止所有攻击途径, 我们已决定进行相关更改

Credential Management API 现在包含原始密码 存储在返回的凭据对象中,以便您能以纯文本形式访问它。 您可以使用现有方法将凭据信息传送到服务器:

navigator.credentials.get({
    password: true,
    federated: {
    providers: [ 'https://accounts.google.com' ]
    },
    mediation: 'silent'
}).then(passwordCred => {
    if (passwordCred) {
    let form = new FormData();
    form.append('email', passwordCred.id);
    form.append('password', passwordCred.password);
    form.append('csrf_token', csrf_token);
    return fetch('/signin', {
        method: 'POST',
        credentials: 'include',
        body: form
    });
    } else {

    // Fallback to sign-in form
    }
}).then(res => {
    if (res.status === 200) {
    return res.json();
    } else {
    throw 'Auth failed';
    }
}).then(profile => {
    console.log('Auth succeeded', profile);
});

自定义提取即将被弃用

如需确定您是否使用自定义 fetch() 函数, 检查使用的是 PasswordCredential 对象还是 FederatedCredential 对象 以 credentials 属性的值的形式表示,例如:

fetch('/signin', {
    method: 'POST',
    credentials: c
})

使用上一个代码示例中所示的常规 fetch() 函数, 或使用 XMLHttpRequest

Chrome 60 之前的版本, “navigator.credentials.get()”接受了可选的 unmediated 属性 一个布尔标志例如:

navigator.credentials.get({
    password: true,
    federated: {
    providers: [ 'https://accounts.google.com' ]
    },
    unmediated: true
}).then(c => {

    // Sign-in
});

设置 unmediated: true 可防止浏览器显示账号选择器 在传递凭据时调用的。

该标记现在已扩展为中介。 在以下情况下,可以使用用户中介:

  • 用户需要选择用于登录的账号。

  • 用户想明确登录 在 navigator.credentials.requireUseMediation() 调用后。

mediation 值选择以下选项之一:

mediation 与布尔标志比较 行为
silent 等于 unmediated: true 凭据已通过,但未显示账号选择器。
optional 等于 unmediated: false 在以下情况下显示账号选择器: 之前调用了 preventSilentAccess()
required 新选项 始终显示账号选择器。 如果您想允许用户切换账号,此类别非常有用 使用原生账号选择器对话框进行设置。

在此示例中 在不显示账号选择器的情况下传递凭据, 等同于前一个标志 unmediated: true

navigator.credentials.get({
    password: true,
    federated: {
    providers: [ 'https://accounts.google.com' ]
    },
    mediation: 'silent'
}).then(c => {

    // Sign-in
});

requireUserMediation() 已重命名为 preventSilentAccess()

为了与 get() 调用中提供的新 mediation 属性完美保持一致, navigator.credentials.requireUserMediation() 方法已重命名为 navigator.credentials.preventSilentAccess()

重命名后,该方法会阻止传递凭据而不显示账号选择器 (有时在不使用用户中介的情况下调用)。 当用户退出网站或取消注册时,此设置非常有用 并且不希望在下次访问时就自动重新登录。

signoutUser();
if (navigator.credentials) {
    navigator.credentials.preventSilentAccess();
}

使用新方法 navigator.credentials.create() 异步创建凭据对象

您现在可以选择异步创建凭据对象 并使用新方法 navigator.credentials.create()。 请继续阅读,比较同步和异步方法。

创建 PasswordCredential 对象

同步方法
let c = new PasswordCredential(form);
异步方法(新增)
let c = await navigator.credentials.create({
    password: form
});

或者:

let c = await navigator.credentials.create({
    password: {
    id: id,
    password: password
    }
});

创建 FederatedCredential 对象

同步方法
let c = new FederatedCredential({
    id:       'agektmr',
    name:     'Eiji Kitamura',
    provider: 'https://accounts.google.com',
    iconURL:  'https://*****'
});
异步方法(新增)
let c = await navigator.credentials.create({
    federated: {
    id:       'agektmr',
    name:     'Eiji Kitamura',
    provider: 'https://accounts.google.com',
    iconURL:  'https://*****'
    }
});

迁移指南

是否已实现 Credential Management API?我们提供了迁移指南文档 请遵循以下步骤来升级到新版本。