第三方登录凭证管理

    一些大型的站点平台都会开放相应的第三方登录接口和说明文档,如国内的有:

    国外的有:

    同样需要调用方法 进行第三方登录凭证存储,只不过存入的凭证类型为 FederatedCredentialFederatedCredential 同样实现了 Credential 接口,同时还新增了 provider 字段作为第三方登录提供方的标识符。因此 FederatedCredential 初始化参数对象应包含以下信息:

    • id: 必须 账户名
    • provider: 必须 第三方登录提供方网址
    • name: 非必需 用户名
    • iconURL: 非必需 用户头像

    其中 provider 要求必须是完整的带协议头的 URL 地址。我们可以在控制台做如下实验:

    可以看到,浏览器会校验 provider 的格式,当格式不符合 URL 格式时会抛出错误。

    这样,我们就可以使用 FederatedCredential 对第三方登录信息进行存储啦。

    例如:

    在前文凭据获取章节中提到,navigator.credentials.get(options) 方法传入参数包含一个字段 federated,可以通过这个字段去读取第三方登录的凭证信息。

    • options.federated: 第三方登录
      {Object}
      • providers:
        {Array} 联合登录账号供应者 id 组成的数组

    例如:

    1. navigator.credentials.get({
    2. federated: {
    3. providers: ['https://www.baidu.com', 'https://www.weibo.com', 'https://www.github.com']
    4. }
    5. });

    这些 providers 需要与 FederatedCredential 第三方登录凭证信息的 provider 相一致。

    这样假设存入的第三方登录凭证如下:

    则在弹出的账号选择列表中,就可以看到如下所示的账号信息:

    第三方账号信息

    那些带有提供方描述字样的信息就是对应的第三方登录凭证信息。没错,不同于密码凭证信息,第三方登录凭证信息会拿 id 字段作为账号的标识。

    对于不同的第三方登录具有不同的处理方式,因此在获取到第三方登录凭证信息之后,需要通过 typeprovider 字段进行凭证信息分类处理,如:

    1. navigator.credentials.get({
    2. password: true,
    3. federated: {
    4. providers: ['https://www.baidu.com', 'https://www.weibo.com']
    5. }
    6. })
    7. .then(function (cred) {
    8. switch (cred.type) {
    9. case 'password':
    10. case 'federated':
    11. // FederatedCredential 凭证处理
    12. switch (cred.provider) {
    13. case 'https://www.baidu.com':
    14. // 调起百度第三方登录
    15. case 'https://www.weibo.com':
    16. // 调起微博第三方登录
    17. }
    18. }
    19. }
    20. });

    第三方登录界面如下:

    点击登录界面的百度登录按钮,即可触发模拟第三方登录。相关代码如下:

    1. $btn.addEventListener('click', function () {
    2. let provider = this.dataset.provider;
    3. // 假装 fetch('./third-party.json') 是调用百度第三方登录的过程
    4. fetch('./third-party.json')
    5. .then(res => {
    6. if (res.status === 200) {
    7. return res.json();
    8. }
    9. return Promise.reject(res.status);
    10. })
    11. // 此处假装第三方登录并授权成功
    12. .then(data => {
    13. // 此处调用凭证管理 API 进行第三方登录信息存储
    14. if (navigator.credentials) {
    15. // 生成第三方登录凭证
    16. let cred = new FederatedCredential({
    17. id: data.uid,
    18. provider: provider,
    19. name: data.name,
    20. iconURL: data.icon
    21. });
    22. return navigator.credentials.store(cred)
    23. .then(() => {
    24. return data;
    25. });
    26. }
    27. return Promise.resolve(data);
    28. })
    29. // 存储完成后再跳转至登录成功页
    30. .then(data => {
    31. window.location.href = './main.html?from=third-party&username=' + data.name;
    32. });
    33. });

    其中模拟第三方授权登录的 third-party.json 返回如下:

    跳转到成功页时将提示如下信息:

    是否保存账号对话框

    点击保存并重新打开登录页面时,将弹出如下账号选择器:

    1. if (navigator.credentials) {
    2. navigator.credentials.get({
    3. password: true,
    4. federated: {
    5. providers: ['https://www.baidu.com']
    6. }
    7. })
    8. .then(cred => {
    9. if (cred) {
    10. switch (cred.type) {
    11. case 'federated':
    12. // FederatedCredential 凭证处理
    13. switch (cred.provider) {
    14. case 'https://www.baidu.com':
    15. // 调起百度第三方登录
    16. window.location.href = './main.html?from=third-party&username=' + cred.name;
    17. }
    18. // ...
    19. }
    20. }
    21. }