原理流程:
通过三大运营商和uniCloud云函数,以移动网络(流量)去鉴别手机号,用户只需要点击“登录”按钮,前端开发者就可以获取到手机号,将这个手机号通过接口传递给后端,后端一般会给一个一键登录接口,后端拿到以后进行处理将登录凭证(token)给到前端,前端存储本地,完成一键登录操作;
因此,对于用户来说,一键登录的必须条件为:
1、手机设备打开“移动网络”,且手机号可用(可发送短信,拨打电话,充值流量,且为正规手机号码);
2、当前手机号运营商在为联通、移动、电信,三家之中;
3、手机有信号,可以完成后续运营商内部获取手机号的过程;
由于虽然上述条件绝大部分用户都满足,但是因为有限制条件,所以经常会出现“一键登录不稳定的情况”;
uniapp官方文档截图:
开启一键登录步骤:
一、首先先在uniapp官网的开发者后台上开通一键登录,获得ApiKey和ApiSecret
接下来我将会详细逐条说明此申请表单含义
DCloud AppId:
使用一个uniapp账号在HbuliderX创建项目的时候,会自动在对应后台生成一个项目管理,这个项目就是中会有一个DCloud AppId
登录对应账号的开发者后台即可看到
应用名称:
当前app要上架的正式名称,如果不知道可以先填一个用途,例如“XX类型APP一键登录”
选择平台:
建议ios与android都勾选,否则后期无法修改只能重新创建一个
Android 包名:
HbuliderX这里
Android 应用签名MD5、Android 应用签名SHA256:
这两个需要申请安卓证书,进入uniapp的开发者后台,登录对应账号,找到要开通一键登录的应用
在证书详情中,即可看到填写一键登录表单对应的数据:Android 应用签名MD5、Android 应用签名SHA256
iOS BundleId:
根据上面的信息,完成一键登录信息填写申请,通过审核以后去后台拿到ApiKey和ApiSecret
二、前端代码
云函数代码
右击项目先选择一个云环境,然后在其中创建云函数
一键登录代码例:云函数为getPhoneNumber,其中创建两个文件
1、index.js
'use strict';
const db = uniCloud.database()
exports.main = async (event, context) => {
const res = await uniCloud.getPhoneNumber({
appid: '', // 替换成自己开通一键登录的应用的DCloud appid
provider: 'univerify',
apiKey: '', // 开发者后台的apiKey
apiSecret: '', // 开发者后台的apiSecret
access_token: event.access_token,
openid: event.openid
});
console.log(res); // 返回数据数据格式为 { code: 0, success: true, phoneNumber: '你的手机号' }
return {
code: 0,
message: '获取手机号成功',
phoneNumber: res.phoneNumber
}
};
2、package.json
{
"name": "getPhoneNumber",
"extensions": {
"uni-cloud-verify": {}
}
}
完成后右键云函数文件上传部署
本地代码:
在需要使用一键登录的地方写一个点击事件,逻辑部分复制了以后看一下注释,有些需要根据业务需求手动更改,别c过去直接用
<!-- html部分,仅为示例 -->
<button @click="oneKeyFun">一键登录</button>
//逻辑部分:
//这是一个点击事件,要写到methods里的
oneKeyFun() {
uni.preLogin({ //预登录
provider: 'univerify', //用手机号登录
success(res) {//如果预登录成功
uni.login({//调用uni登录,获取前置必要参数
provider: 'univerify',
univerifyStyle: {
//参考`univerifyStyle 数据结构`
"icon": {
"path": "static/logo/onekeyLogo.png" // 自定义显示在授权框中的logo,仅支持本地图片 默认显示App logo
},
"authButton": {
"normalColor": "#F83D3D", // 授权按钮正常状态背景颜色 默认值:#3479f5
"highlightColor": "#F83D3D", // 授权按钮按下状态背景颜色 默认值:#2861c5(仅ios支持)
},
"privacyTerms": {
"defaultCheckBoxState": false, // 条款勾选框初始状态 默认值: true
},
},
success(res) { // 登录成功
console.log(res.authResult); // {openid:'登录授权唯一标识',access_token:'接口返回的 token'}
uniCloud.callFunction({//在这里调用一键登录的云函数
name: 'getPhoneNumber', // 你的云函数名称,别瞎跟着我写
data: {
'access_token': res.authResult.access_token, // 客户端一键登录接口返回的access_token
'openid': res.authResult.openid // 客户端一键登录接口返回的openid
}
}).then(res => {
console.log(res)//如果云函数调用成功数据里就会有你的手机号,拿着请求后端接口,让他进行后续的注册登录处理
}).catch(err => {
// 处理错误
if (err) {
uni.showToast({
icon: "none",
title: "您的手机号暂不支持一键登录,请尝试其它登录方式"
});
// 建议跳转普通登录
setTimeout(() => {
// 关闭一键登录弹框
uni.closeAuthView();
uni.redirectTo({
url: "你的普通登录页面路径"
});
}, 1000);
return false;
}
})
},
fail(res) { // uni登录失败
if (err) {
uni.showToast({
icon: "none",
title: "您的手机号暂不支持一键登录,请尝试其它登录方式"
});
// 建议跳转普通登录
setTimeout(() => {
// 关闭一键登录弹框
uni.closeAuthView();
uni.redirectTo({
url: "你的普通登录页面路径"
});
}, 1000);
return false;
}
}
})
},
fail(err) { //预登录失败
if (err) {
uni.showToast({
icon: "none",
title: "您的手机号暂不支持一键登录,请尝试其它登录方式"
});
// 建议跳转普通登录
setTimeout(() => {
// 关闭一键登录弹框
uni.closeAuthView();
uni.redirectTo({
url: "你的普通登录页面路径"
});
}, 1000);
return false;
}
}
})
},
uniapp一键登录会唤出一个弹框,弹框的样式可以参考官方文档进行设置
关于开发一键登录功能时需要注意的点
1、需要使用真机调试来测试,直接用H5模拟器来测试肯定会报错,如果不清楚如何真机调试或遇到真机调试问题,参考我的这篇博客
2、一键登录功能在正式上线前需要充值,注意后台开发者的余额,0.02元/次,失败不计费,目前只支持中国大陆地区用户。但在实际使用中需要依赖uniCloud云服务,在使用阿里云正式版后,每次大约需要多花0.0000139元
3、一键登录经常会出现好像有时正常有时不正常的情况,但其实只要真机成功一次,基本就说明代码没有问题,可以排查以下问题:
1、当前是否还有余额
2、阿里或腾讯云是否需要续费
3、出现问题的设备是否有正常插入手机卡
4、此手机卡是否欠费,能否正常发送短信和接听电话
5、是否为双卡双待的一个电话卡一个流量卡,纯流量卡不能用于一键登录,注意设置中的流量使用是否为电话卡
6、网络是否出现波动,手机设备是否没有信号
一键登录经常会遇到的问题:
1、真机调试连接成功,但控制台不打印数据
排查以下问题:
1、当前代码有没有上传云端,是否连接的是否为云端控制台
2、当前HbuliderX版本是否为最新,过旧的HbuliderX版本真机调试无法打印数据
2、无法唤起自带弹框,一直转圈等其它问题
打印代码,通过catch捕获错误,然后在uniapp的官方文档上查找对应错误解决
附录
感谢前人的经验分享,本文实现过程借鉴参考以下文档博客:
迷途者寻影而行
https://www.cnblogs.com/pkkyh/p/14631381.html
uniapp官方文档
https://uniapp.dcloud.net.cn/uniCloud/univerify.html#
bye~