HBuilderX 3.0+版本,新增一键登录,运营商网关认证,免短信验证获取手机号;刚好最近开发项目有应用上,简单分享一下!
1、开通uniapp的“一键登录”权限
在minifest.json文件中勾选一键登录(univerify)
2、申请云开发空间,开通地址(https://unicloud.dcloud.net.cn)
3、在项目中创建“云函数”
方法名自己定义即可,创建完后在 index.js 填入以下获取手机号码的云函数代码:
'use strict';
exports.main = async (event, context) => {
let req = event.queryStringParameters; // 该参数为获取后端传递的access_token和openid,具体变量可以通过console.log打印查看
const res = await uniCloud.getPhoneNumber({
appid: '__UNI__1222', // 替换成自己开通一键登录的应用的DCloud appid,使用callFunction方式调用时可以不传(会自动取当前客户端的appid),如果使用云函数URL化的方式访问必须传此参数
provider: 'univerify',
apiKey: 'xxxx', // 在开发者中心开通服务并获取apiKey
apiSecret: 'xxxx', // 在开发者中心开通服务并获取apiSecret
access_token: req.access_token,
openid: req.openid
})
// 执行入库等操作,正常情况下不要把完整手机号返回给前端
return {
code: 0,
message: '获取手机号成功',
content: res // res里面包含了成功获取的真实手机号码
}
};
保存代码后右击函数目录,选择“上传部署”;
4、前端实现调用
toLogin(){
var _this = this;
uni.preLogin({
provider:"univerify",
success() {
uni.hideLoading();
uni.login({
provider:"univerify",
univerifyStyle:{},// 自定义授权页面信息,参数参考文档 https://uniapp.dcloud.io/univerify
success(res) {
let loginRes = res.authResult;
// loginRes : {openid:'deviceIDlength+deviceID+gyuid',access_token:'接口返回的 token'}
requestLogin(); // 执行后端请求逻辑
},
fail(fres) {
uni.closeAuthView(); // 关闭一键登录弹出窗口
if(fres.code == 30002){ // 点击其他方式登陆
uni.navigateTo({
url:"login/login",
animationType: 'slide-in-bottom',
animationDuration: 200
})
}
// 30003 关闭登陆
},
complete() {
uni.closeAuthView();
}
})
},
fail(res) {
console.log('error',res);
}
})
}
5、后端根据access_token和openid换取手机号码;以thinkphp为例
/**
* 一键登陆
*/
public function univerify(Request $request){
$secret = "这里填写一键登录申请通过后的AppSecret";
$sign = $this->getSignature($request->post(),$secret);
$requestUrl = "uniCloud后台获取的请求地址?sign=".$sign."&".http_build_query($request->post());
$result = json_decode(file_get_contents($requestUrl),true);
// 数据返回格式,自行打印查看
// {
// code: 0,
// message: '',
// phoneNumber: '138xxxxxxxx'
// }
if($result['code'] && isset($result['content']['phoneNumber'])){
$mobile = $result['content']['phoneNumber']; // 实际获取手机号码
}
}
/**
* 获取签名
* @param array $arrdata 签名数组
* @param string $key 密钥
* @return boolean|string 签名值
*/
protected function getSignature($arrdata,$key) {
ksort($arrdata);
$paramstring = "";
foreach($arrdata as $key => $value)
{
if(strlen($paramstring) == 0)
$paramstring .= $key . "=" . $value;
else
$paramstring .= "&" . $key . "=" . $value;
}
$stringSignTemp = rtrim($paramstring, '&');
$paySign = hash_hmac('sha256',$stringSignTemp,$key);
return $paySign;
}
6、前端获取手机号码
通过官方提供的云函数调用方法
uniCloud.callFunction({
name:"云函数名",
data:{
"access_token":loginRes.access_token,
"openid":loginRes.openid
}
}).then((res)=>{
console.log(res); // res 内容则包含手机号码
}).catch(){
// 执行失败
}
7、云函数请求地址获取