0
点赞
收藏
分享

微信扫一扫

凭证管理 保存密码

Sophia的玲珑阁 2021-09-24 阅读 81
一点点

登录流程需要完成以下三步

  1. 实现异步登录;
  2. 登录成功后调用凭证管理 API 进行登录信息存储;
  3. 完成登录成功后页面切换或者是 UI 更新之类的操作。

凭据存储

调用 navigator.credentials.store() 这个方法进行登录信息存储。由于仅有部分浏览器支持凭据管理 API,因此在使用前需要进行方法是否存在的判断:

if (navigator.credentials) {
    // 使用 navigator.credentials.store 进行凭证存储
}

  • 凭证管理 API 提供了两凭据对象:PasswordCredential 和 FederatedCredential,这两种凭据对象均实现了 Credential 的接口,可以分别针对 账号密码登录 和 第三方登录 两种模式的登录信息进行存储。

凭据获取

  • 过 navigator.credentials.get() 方法,可以获取同个域名下用户存储的登录信息。
if (navigator.credentials) {
    navigator.credentials.get({
        password: true
    });
}

  • 参数
  1. password: {boolean} 是否支持通过密码认证登录
  2. federated: 第三方登录 {Object}
    • providers: {Array} 联合登录账号供应者 id 组成的数组
  3. unmediated: {boolean} 是否显示账号选择器 如果只有一个账号,自动填充

获取账号密码登录凭证

只有当 options.password === true 时,账号选择器才会展示类型为 PasswordCredential 的登录信息。

退出登录

  • 当用户退出网站时,应该确保用户在下次访问的时候不会自动登录。可以通过调用 navigator.credentials.requireUserMediation() 或 navigator.credentials.preventSilentAccess() 来关闭自动登录。Chrome 60+ 后,requireUserMediation 被重命名为 preventSilentAccess,请注意兼容。
app.logout = function () {
    // 处理登出流程
    if (navigator.credentials.requireUserMediation) {
        navigator.credentials.requireUserMediation();
    }
    else if (navigator.credentials.preventSilentAccess) {
        navigator.credentials.preventSilentAccess();
    }
};

栗子

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <form id="test-form">
        <input type="text" name="username">
        <input type="password" name="password">
        <input type="submit" value="提交">
    </form>
    <button>退出登录(不保存凭证)</button>
    <!-- <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> -->
    <script>
        var form = document.querySelector('#test-form');
        var username = document.querySelector('input[name=username]');
        var password = document.querySelector('input[name=password]');
        var btn = document.querySelector('button');

        form.addEventListener('submit', function(e) {
            e.preventDefault();

            // $.ajax({
            //         url: './test.php',
            //         type: 'json',
            //         data: {
            //             username: formData.get('username'),
            //             password: formData.get('password')
            //         },
            //         success: function(res) {
            //             console.log('ok', res)
            //                 // 后续操作
            //         },
            //         error: function(err) {
            //             console.log('err', err)
            //                 // 错误操作
            //         }
            //     })
            // return false;
            var formData = new FormData(form);
            fetch('./test.php', {
                    method: "POST",
                    body: formData,
                    mode: "no-cors",
                    cache: "force-cache"
                })
                .then(res => {
                    console.log('first', res);
                    if (res.status === 200) {
                        return res.json();
                    }

                    return Promise.reject(res.status);
                })
                .then(data => {
                    saveCredentials(data, formData.get('username'), formData.get('password'));
                    console.log('second', data);
                })
                .catch(err => {
                    console.log('fetch is Failed: ' + err);
                })
        })

        function saveCredentials(data, username, password) {
            if (navigator.credentials) {
                var cred = new PasswordCredential({
                    id: username,
                    password: password,
                    // name: username, // 可选
                    // iconURL: data.icon   // 可选
                });
                navigator.credentials.store(cred).then(cred => {
                    console.log('cred', cred);
                    // 后续操作
                });
            }
        }
        if (navigator.credentials) {
            navigator.credentials.get({
                    password: true,
                    // federated: {     // 第三方登录
                    //     providers: ['https://www.baidu.com']
                    // },
                                        unmediated: true // 是否显示账号选择器 (只有一个账号的情况下触发, 可以用登出取消自动填充)
                })
                .then(cred => {
                    // cred 可能为 undefined
                    if (cred) {
                        switch (cred.type) {
                            case 'password':
                                // 对 PasswordCredential 凭证进行处理
                                console.log(cred)
                                username.value = cred.id;
                                password.value = cred.password;
                                break;
                            default:
                                break;
                        }
                    }
                });
        }
        btn.addEventListener('click', () => {
            // 处理登出流程  (取消自动登录)
            if (navigator.credentials.requireUserMediation) {
                navigator.credentials.requireUserMediation().then(() => {
                        console.log('登出成功')
                    })
                    .catch(() => {
                        console.log('登出失败')
                    });;
            } else if (navigator.credentials.preventSilentAccess) {
                navigator.credentials.preventSilentAccess().then(() => {
                        console.log('登出成功')
                    })
                    .catch(() => {
                        console.log('登出失败')
                    });;
            }
        })
    </script>

</body>

</html>

参考来源: https://lavas.baidu.com/pwa/automatic-login/credential-management-api/introduction

举报

相关推荐

0 条评论