指纹登录
这个函数接收2个参数:用户凭证、设备id,我们会通过这两个参数来调起客户端的指纹设备来验证身份,具体的实现代码如下:
touchIDLogin: async function(certificate: string, touchId: string) { // 校验设备是否支持touchID const hasTouchID = await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable(); if (hasTouchID) { // 更新登录凭证 this.touchIDLoginOptions.publicKey.challenge = this.base64ToArrayBuffer( certificate ); // 更新touchID this.touchIDLoginOptions.publicKey.allowCredentials[0].id = this.base64ToArrayBuffer( touchId ); // 开始校验指纹 await navigator.credentials.get(this.touchIDLoginOptions); // 调用指纹登录接口 this.$api.touchIdLogingAPI .touchIdLogin({ touchId: touchId, certificate: certificate }) .then((res: responseDataType) => { if (res.code == 0) { // 存储当前用户信息 localStorage.setItem("token", res.data.token); localStorage.setItem("refreshToken", res.data.refreshToken); localStorage.setItem("profilePicture", res.data.avatarSrc); localStorage.setItem("userID", res.data.userID); localStorage.setItem("username", res.data.username); const certificate = res.data.certificate; localStorage.setItem("certificate", certificate); // 跳转消息组件 this.$router.push({ name: "message" }); return; } // 切回登录界面 this.isLoginStatus = loginStatusEnum.NOT_LOGGED_IN; alert(res.msg); }); } }
注意⚠️:注册新的指纹后,旧的Touch id就会失效,只能通过新的Touch ID来登录,否则系统无法调起指纹设备,会报错:认证出了点问题。
整合现有登录逻辑
完成上述步骤后,我们已经实现了整个指纹的注册、登录的逻辑,接下来我们来看看如何将其与现有登录进行整合。
调用指纹注册
当用户使用用户名、密码或者第三方平台授权登录成功后,我们就调用指纹注册函数,提示用户是否对本网站进行授权,实现代码如下:
authLogin: function(state: string, code: string, platform: string) { this.$api.authLoginAPI .authorizeLogin({ state: state, code: code, platform: platform }) .then(async (res: responseDataType) => { if (res.code == 0) { // ... 授权登录成功,其他代码省略 ... // // 保存用户凭证,用于指纹登录 const certificate = res.data.certificate; localStorage.setItem("certificate", certificate); // 校验设备是否支持touchID const hasTouchID = await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable(); if (hasTouchID) { // ... 其他代码省略 ... // // 获取Touch ID,检测用户是否已授权本网站指纹登录 this.$api.touchIdLogingAPI .getTouchID({ userId: userId }) .then(async (res: responseDataType) => { if (res.code !== 0) { // touchId不存在, 询问用户是否注册touchId await this.touchIDRegistered(username, userId, certificate); } // 保存touchid localStorage.setItem("touchId", res.data); // 跳转消息组件 await this.$router.push({ name: "message" }); }); return; } // 设备不支持touchID,直接跳转消息组件 await this.$router.push({ name: "message" }); return; } // 登录失败,切回登录界面 this.isLoginStatus = loginStatusEnum.NOT_LOGGED_IN; alert(res.msg); }); }
最终的效果如下所示:
每次第三方平台授权登录时都会检测当前用户是否已授权本网站,如果已授权则将Touch ID保存至本地,用于通过指纹直接登录。
调用指纹登录
当登录页面加载完毕1s后,我们从用户本地取出用户凭证与Touch ID,如果存在则提示用户是否需要通过指纹来登录系统,具体代码如下所示:
mounted() { const touchId = localStorage.getItem("touchId"); const certificate = localStorage.getItem("certificate"); // 如果touchId存在,则调用指纹登录 if (touchId && certificate) { // 提示用户是否需要touchId登录 setTimeout(() => { if (window.confirm("您已授权本网站通过指纹登录,是否立即登录?")) { this.touchIDLogin(certificate, touchId); } }, 1000); } }
最终效果如下所示:
项目地址
本文代码的完整地址请移步:Login.vue
- 在线体验地址:chat-system
- 项目GitHub地址:chat-system-github
写在最后
最近打算换工作,有没有广州这边的公司可以内推我呀😁,我的微信:Baymax-kt
- 公众号无法外链,如果文中有链接,可点击下方阅读原文查看😊