登录用户

Meggin Kearney
Meggin Kearney

要让用户登录,请从浏览器密码中检索凭据 并将其用于自动登录用户。 对于拥有多个账号的用户, 让他们使用账号选择器一键选择账号。

自动登录

您可以在网站上的任何位置自动登录; 不仅包括首页,还包括其他叶级页。 当用户访问您网站上的不同网页时,这种匹配类型非常有用。 。

如需启用自动登录,请执行以下操作:

  1. 获取凭据信息。
  2. 对用户进行身份验证。
  3. 更新界面或前往个性化页面。

获取凭据信息

浏览器支持

  • 51
  • 18
  • 60
  • 13

来源

要获取凭据信息,请调用 navigator.credentials.get()。 指定要请求的凭据类型 方法是为其指定 passwordfederated

始终使用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 属性, 其值为 passwordfederated

如果 .typefederated.provider 属性是一个表示身份提供方的字符串。

对用户进行身份验证

获得凭据后 根据凭据类型运行身份验证流程, passwordfederated

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

别忘了显示身份验证错误消息

为了避免用户混淆 用户应该会看到显示“正在登录”的蓝色消息框 在获取凭据对象时触发:

显示用户正在登录的蓝色消息框。

重要提示:如果您成功获取了凭据对象 但无法验证用户身份,则应显示错误消息:

        }).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 账号选择器。

通过账号选择器登录的步骤与 自动登录、 另一个调用,以显示账号选择器 来获取凭据信息:

  1. 获取凭据信息并显示账号选择器。
  2. 对用户进行身份验证
  3. 更新界面或前往个性化页面

获取凭据信息并显示账号选择器

为响应指定的用户操作显示账号选择器; 例如,当用户点按“登录”时按钮。致电 navigator.credentials.get(), 并添加 mediation: 'optional'mediation: 'required' 以显示账号选择器。

如果 mediationrequired,系统会始终向用户显示用于登录的账号选择器。 通过此选项,具有多个账号的用户可在账号间轻松切换。 当 mediationoptional 时, 在用户登录后,系统会明确向用户显示 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';
      });
  }
});

联合登录

借助联合登录,用户只需点按一下即可登录, 而无需记住您网站的其他登录详细信息。

如需实现联合登录,请执行以下操作:

  1. 使用第三方身份对用户进行身份验证。
  2. 存储身份信息。
  3. 更新界面或进入个性化页面(与自动登录相同)。

使用第三方身份对用户进行身份验证

当用户点按联合登录按钮时 使用 FederatedCredential

浏览器支持

  • 51
  • 79
  • x
  • x

来源

例如,如果提供商是 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 ConnectOAuth。 如需了解如何使用联合账号进行身份验证, 指的是各自的联合身份提供方文档。 热门示例包括:

存储身份信息

完成身份验证后,您可以存储身份信息。 您要在此处存储的信息是身份提供方提供的id 以及表示身份提供方的提供方字符串 (nameiconURL 是可选的)。 有关详情,请参阅 凭据管理规范

如需存储联合账号详情,请实例化一个新的 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();
}

这样可以确保用户下次启用自动登录功能时,系统就不会自动登录。 如需恢复自动登录,用户可以选择刻意登录 只需从账号选择器中选择想要登录的账号即可。 然后,在他们明确退出之前,用户始终会重新登录。

反馈