流程列表
- DCloud开放平台申请ApiKey和ApiSecret
- 创建云对象并引用手机号一键登录扩展库
- 客户端一键登录逻辑
- 完整代码
具体流程步骤
-
申请ApiKey和ApiSecret
点击开发者中心登录,进入开发者后台,选择一键登录下的基础配置
-
创建云对象并引用扩展库
创建login云对象
引用扩展库
右键选择管理公共模块或扩展库依赖
选择对应扩展库 uni-cloud-verify
查看login云对象下的package.json会多一个uni-cloud-verify扩展
云函数逻辑
async univerifyLogin(data) {
let res = await uniCloud.getPhoneNumber({
appid: '__UNI__EBC5FCF', //应用标识,可以在manifest.json基础配置查看也可以在开发者中心应用管理-我的应用查看
provider: 'univerify',
apiKey: 'xxxxxxx', // 在开发者中心开通服务并获取apiKey
apiSecret: 'xxxxxxx', // 在开发者中心开通服务并获取apiSecret
access_token: data.access_token, //由客户端传入
openid: data.openid //由客户端传入
})
return {
code: 200,
data: res.data,
msg: '获取手机号成功'
}
}
- 客户端逻辑
客户端逻辑除调用云对象外都是借鉴的文档
fastLoginFn() {
var this_ = this
// 预登陆
uni.preLogin({
provider: "univerify",
success: () => {
uni.login({
provider: "univerify",
univerifyStyle: {
"fullScreen": false, // 是否全屏显示,默认值: false
"backgroundColor": "#ffffff", // 授权页面背景颜色,默认值:#ffffff
"backgroundImage": "", // 全屏显示的背景图片,默认值:"" (仅支持本地图片,只有全屏显示时支持)
"icon": {
"path": "static/xxx.png" // 自定义显示在授权框中的logo,仅支持本地图片 默认显示App logo
},
"closeIcon": {
"path": "static/xxx.png" // 自定义关闭按钮,仅支持本地图片。 HBuilderX3.3.7+版本支持
},
"phoneNum": {
"color": "#202020" // 手机号文字颜色 默认值:#202020
},
"slogan": {
"color": "#BBBBBB" // slogan 字体颜色 默认值:#BBBBBB
},
"authButton": {
"normalColor": "#3479f5", // 授权按钮正常状态背景颜色 默认值:#3479f5
"highlightColor": "#2861c5", // 授权按钮按下状态背景颜色 默认值:#2861c5(仅ios支持)
"disabledColor": "#73aaf5", // 授权按钮不可点击时背景颜色 默认值:#73aaf5(仅ios支持)
"textColor": "#ffffff", // 授权按钮文字颜色 默认值:#ffffff
"title": "本机号码一键登录", // 授权按钮文案 默认值:“本机号码一键登录”
"borderRadius": "24px" // 授权按钮圆角 默认值:"24px" (按钮高度的一半)
},
"otherLoginButton": {
"visible": true, // 是否显示其他登录按钮,默认值:true
"normalColor": "", // 其他登录按钮正常状态背景颜色 默认值:透明
"highlightColor": "", // 其他登录按钮按下状态背景颜色 默认值:透明
"textColor": "#656565", // 其他登录按钮文字颜色 默认值:#656565
"title": "其他登录方式", // 其他登录方式按钮文字 默认值:“其他登录方式”
"borderColor": "", //边框颜色 默认值:透明(仅iOS支持)
"borderRadius": "0px" // 其他登录按钮圆角 默认值:"24px" (按钮高度的一半)
},
"privacyTerms": {
"defaultCheckBoxState": true, // 条款勾选框初始状态 默认值: true
"isCenterHint": false, //未勾选服务条款时点击登录按钮的提示是否居中显示 默认值: false (3.7.13+ 版本支持)
"uncheckedImage": "", // 可选 条款勾选框未选中状态图片(仅支持本地图片 建议尺寸 24x24px)(3.2.0+ 版本支持)
"checkedImage": "", // 可选 条款勾选框选中状态图片(仅支持本地图片 建议尺寸24x24px)(3.2.0+ 版本支持)
"checkBoxSize": 12, // 可选 条款勾选框大小,仅android支持
"textColor": "#BBBBBB", // 文字颜色 默认值:#BBBBBB
"termsColor": "#5496E3", // 协议文字颜色 默认值: #5496E3
"prefix": "我已阅读并同意", // 条款前的文案 默认值:“我已阅读并同意”
"suffix": "并使用本机号码登录", // 条款后的文案 默认值:“并使用本机号码登录”
"privacyItems": [ // 自定义协议条款,最大支持2个,需要同时设置url和title. 否则不生效
{
"url": "https://", // 点击跳转的协议详情页面
"title": "用户服务协议" // 协议名称
}
]
},
},
success: (res) => {
console.log("一键登录调用返回的数据", res)
uniCloud
.callFunction({
name: "login", // 云函数名称
data: {
access_token: res.authResult.access_token, // 客户端一键登录接口返回的access_token
openid: res.authResult.openid // 客户端一键登录接口返回的openid
}
})
.then((dataRes) => {
console.log("云函数返回的参数", dataRes)
let phone = dataRes.result.data.phoneNumber
this.userPhone = dataRes.result.data.phoneNumber
// 这里进行登录操作
})
.catch((err) => {
console.log("云函数报错", err)
uni.showToast({
title: err.errMsg,
icon: "none"
})
this_ = this
setTimeout(() => {
uni.closeAuthView() //关闭一键登录弹出窗口
}, 500)
})
uni.showToast({
title: res.authResult,
icon: "none"
})
// console.log("云函数调用返回数据", dataRes)
},
fail(err) {
// 登录失败或者点击其他登录方式,自定义按钮等
console.log("一键登录uni.login失败", err)
uni.showToast({
title: res.errMsg || err.metadata?.resultDesc,
icon: "none"
})
setTimeout(() => {
uni.closeAuthView() //关闭一键登录弹出窗口
}, 500)
}
})
},
fail(res) {
console.log("一键登录uni.preLogin失败", res)
if (res.errMsg != "login:ok") {
// 这里注意有个小坑: 不同运营商,返回的报错字段不同, 经过测试, 以下几乎包含了三大运营商报错字段
uni.showToast({
title: res.errMsg || res.metadata.resultMsg || res.metadata.error_data ||
res.metadata.resultDesc || "请检查是否插入有效sim卡及开启蜂窝数据网络",
icon: "none"
})
}
//如果手机没有插入有效的sim卡,或者手机蜂窝数据网络关闭,
//都有可能造成预登录校验失败。
}
})
}
这里需要注意的是 success成功函数之后调用云对象的方式,刚开始借鉴的网友的一种方式,最后运行到真机上会提示 云函数报错, Error: Method name required
改进如下
fastLoginFn() {
console.log("手机号一键登录")
var this_ = this
// 预登陆
uni.preLogin({
provider: "univerify",
success: () => {
uni.login({
provider: "univerify",
univerifyStyle: {
"fullScreen": false, // 是否全屏显示,默认值: false
"backgroundColor": "#ffffff", // 授权页面背景颜色,默认值:#ffffff
"backgroundImage": "", // 全屏显示的背景图片,默认值:"" (仅支持本地图片,只有全屏显示时支持)
"icon": {
"path": "static/xxx.png" // 自定义显示在授权框中的logo,仅支持本地图片 默认显示App logo
},
"closeIcon": {
"path": "static/xxx.png" // 自定义关闭按钮,仅支持本地图片。 HBuilderX3.3.7+版本支持
},
"phoneNum": {
"color": "#202020" // 手机号文字颜色 默认值:#202020
},
"slogan": {
"color": "#BBBBBB" // slogan 字体颜色 默认值:#BBBBBB
},
"authButton": {
"normalColor": "#3479f5", // 授权按钮正常状态背景颜色 默认值:#3479f5
"highlightColor": "#2861c5", // 授权按钮按下状态背景颜色 默认值:#2861c5(仅ios支持)
"disabledColor": "#73aaf5", // 授权按钮不可点击时背景颜色 默认值:#73aaf5(仅ios支持)
"textColor": "#ffffff", // 授权按钮文字颜色 默认值:#ffffff
"title": "本机号码一键登录", // 授权按钮文案 默认值:“本机号码一键登录”
"borderRadius": "24px" // 授权按钮圆角 默认值:"24px" (按钮高度的一半)
},
"otherLoginButton": {
"visible": true, // 是否显示其他登录按钮,默认值:true
"normalColor": "", // 其他登录按钮正常状态背景颜色 默认值:透明
"highlightColor": "", // 其他登录按钮按下状态背景颜色 默认值:透明
"textColor": "#656565", // 其他登录按钮文字颜色 默认值:#656565
"title": "其他登录方式", // 其他登录方式按钮文字 默认值:“其他登录方式”
"borderColor": "", //边框颜色 默认值:透明(仅iOS支持)
"borderRadius": "0px" // 其他登录按钮圆角 默认值:"24px" (按钮高度的一半)
},
"privacyTerms": {
"defaultCheckBoxState": true, // 条款勾选框初始状态 默认值: true
"isCenterHint": false, //未勾选服务条款时点击登录按钮的提示是否居中显示 默认值: false (3.7.13+ 版本支持)
"uncheckedImage": "", // 可选 条款勾选框未选中状态图片(仅支持本地图片 建议尺寸 24x24px)(3.2.0+ 版本支持)
"checkedImage": "", // 可选 条款勾选框选中状态图片(仅支持本地图片 建议尺寸24x24px)(3.2.0+ 版本支持)
"checkBoxSize": 12, // 可选 条款勾选框大小,仅android支持
"textColor": "#BBBBBB", // 文字颜色 默认值:#BBBBBB
"termsColor": "#5496E3", // 协议文字颜色 默认值: #5496E3
"prefix": "我已阅读并同意", // 条款前的文案 默认值:“我已阅读并同意”
"suffix": "并使用本机号码登录", // 条款后的文案 默认值:“并使用本机号码登录”
"privacyItems": [ // 自定义协议条款,最大支持2个,需要同时设置url和title. 否则不生效
{
"url": "https://", // 点击跳转的协议详情页面
"title": "用户服务协议" // 协议名称
}
]
},
},
success: (res) => {
console.log("一键登录调用返回的数据", res)
// 云对象调用
let data = {
access_token: res.authResult.access_token,
openid: res.authResult.openid
}
let loginInfo = univerify.univerifyLogin(data)
console.log(loginInfo, '手机一键登录结果')
uni.showToast({
title: res.authResult,
icon: "none"
})
// console.log("云函数调用返回数据", dataRes)
},
fail(err) {
// 登录失败或者点击其他登录方式,自定义按钮等
console.log("一键登录uni.login失败", err)
uni.showToast({
title: res.errMsg || err.metadata?.resultDesc,
icon: "none"
})
setTimeout(() => {
uni.closeAuthView() //关闭一键登录弹出窗口
}, 500)
}
})
},
fail(res) {
console.log("一键登录uni.preLogin失败", res)
if (res.errMsg != "login:ok") {
// 这里注意有个小坑: 不同运营商,返回的报错字段不同, 经过测试, 以下几乎包含了三大运营商报错字段
uni.showToast({
title: res.errMsg || res.metadata.resultMsg || res.metadata.error_data ||
res.metadata.resultDesc || "请检查是否插入有效sim卡及开启蜂窝数据网络",
icon: "none"
})
}
//如果手机没有插入有效的sim卡,或者手机蜂窝数据网络关闭,
//都有可能造成预登录校验失败。
}
})
}
至此成功了
- 完整代码
服务端unicloud代码index.obj.js
// 云对象教程: https://uniapp.dcloud.net.cn/uniCloud/cloud-obj
// jsdoc语法提示教程:https://ask.dcloud.net.cn/docs/#//ask.dcloud.net.cn/article/129
module.exports = {
_before: function() { // 通用预处理器
},
async univerifyLogin(data) {
let res = await uniCloud.getPhoneNumber({
appid: '__UNI__EBC5FCF',
provider: 'univerify',
apiKey: 'xxxxxxxxx', // 在开发者中心开通服务并获取apiKey
apiSecret: 'xxxxxx, // 在开发者中心开通服务并获取apiSecret
access_token: data.access_token,
openid: data.openid
})
return {
code: 200,
data: res.data,
msg: '获取手机号成功'
}
}
}
客户端 univerifyLogin.vue代码
<template>
<button @click="fastLoginFn">手机号一键登录</button>
</template>
<script>
let univerify = uniCloud.importObject('login')
export default {
data() {
return {
}
},
onLoad() {
},
methods: {
fastLoginFn() {
console.log("手机号一键登录")
var this_ = this
// 预登陆
uni.preLogin({
provider: "univerify",
success: () => {
uni.login({
provider: "univerify",
univerifyStyle: {
"fullScreen": false, // 是否全屏显示,默认值: false
"backgroundColor": "#ffffff", // 授权页面背景颜色,默认值:#ffffff
"backgroundImage": "", // 全屏显示的背景图片,默认值:"" (仅支持本地图片,只有全屏显示时支持)
"icon": {
"path": "static/xxx.png" // 自定义显示在授权框中的logo,仅支持本地图片 默认显示App logo
},
"closeIcon": {
"path": "static/xxx.png" // 自定义关闭按钮,仅支持本地图片。 HBuilderX3.3.7+版本支持
},
"phoneNum": {
"color": "#202020" // 手机号文字颜色 默认值:#202020
},
"slogan": {
"color": "#BBBBBB" // slogan 字体颜色 默认值:#BBBBBB
},
"authButton": {
"normalColor": "#3479f5", // 授权按钮正常状态背景颜色 默认值:#3479f5
"highlightColor": "#2861c5", // 授权按钮按下状态背景颜色 默认值:#2861c5(仅ios支持)
"disabledColor": "#73aaf5", // 授权按钮不可点击时背景颜色 默认值:#73aaf5(仅ios支持)
"textColor": "#ffffff", // 授权按钮文字颜色 默认值:#ffffff
"title": "本机号码一键登录", // 授权按钮文案 默认值:“本机号码一键登录”
"borderRadius": "24px" // 授权按钮圆角 默认值:"24px" (按钮高度的一半)
},
"otherLoginButton": {
"visible": true, // 是否显示其他登录按钮,默认值:true
"normalColor": "", // 其他登录按钮正常状态背景颜色 默认值:透明
"highlightColor": "", // 其他登录按钮按下状态背景颜色 默认值:透明
"textColor": "#656565", // 其他登录按钮文字颜色 默认值:#656565
"title": "其他登录方式", // 其他登录方式按钮文字 默认值:“其他登录方式”
"borderColor": "", //边框颜色 默认值:透明(仅iOS支持)
"borderRadius": "0px" // 其他登录按钮圆角 默认值:"24px" (按钮高度的一半)
},
"privacyTerms": {
"defaultCheckBoxState": true, // 条款勾选框初始状态 默认值: true
"isCenterHint": false, //未勾选服务条款时点击登录按钮的提示是否居中显示 默认值: false (3.7.13+ 版本支持)
"uncheckedImage": "", // 可选 条款勾选框未选中状态图片(仅支持本地图片 建议尺寸 24x24px)(3.2.0+ 版本支持)
"checkedImage": "", // 可选 条款勾选框选中状态图片(仅支持本地图片 建议尺寸24x24px)(3.2.0+ 版本支持)
"checkBoxSize": 12, // 可选 条款勾选框大小,仅android支持
"textColor": "#BBBBBB", // 文字颜色 默认值:#BBBBBB
"termsColor": "#5496E3", // 协议文字颜色 默认值: #5496E3
"prefix": "我已阅读并同意", // 条款前的文案 默认值:“我已阅读并同意”
"suffix": "并使用本机号码登录", // 条款后的文案 默认值:“并使用本机号码登录”
"privacyItems": [ // 自定义协议条款,最大支持2个,需要同时设置url和title. 否则不生效
{
"url": "https://", // 点击跳转的协议详情页面
"title": "用户服务协议" // 协议名称
}
]
},
},
success: (res) => {
console.log("一键登录调用返回的数据", res)
// 云对象调用
let data = {
access_token: res.authResult.access_token,
openid: res.authResult.openid
}
let loginInfo = univerify.univerifyLogin(data)
console.log(loginInfo, '手机一键登录结果')
// 云函数调用 (由于unicloud创建的是云对象,所以采用以下调用方式会报错----云函数报错, Error: Method name required)
// uniCloud
// .callFunction({
// name: "login", // 云函数名称
// data: {
// access_token: res.authResult.access_token, // 客户端一键登录接口返回的access_token
// openid: res.authResult.openid // 客户端一键登录接口返回的openid
// }
// })
// .then((dataRes) => {
// console.log("云函数返回的参数", dataRes)
// let phone = dataRes.result.data.phoneNumber
// this.userPhone = dataRes.result.data.phoneNumber
// // 这里进行登录操作
// })
// .catch((err) => {
// console.log("云函数报错", err)
// uni.showToast({
// title: err.errMsg,
// icon: "none"
// })
// this_ = this
// setTimeout(() => {
// uni.closeAuthView() //关闭一键登录弹出窗口
// }, 500)
// })
uni.showToast({
title: res.authResult,
icon: "none"
})
// console.log("云函数调用返回数据", dataRes)
},
fail(err) {
// 登录失败或者点击其他登录方式,自定义按钮等
console.log("一键登录uni.login失败", err)
uni.showToast({
title: res.errMsg || err.metadata?.resultDesc,
icon: "none"
})
setTimeout(() => {
uni.closeAuthView() //关闭一键登录弹出窗口
}, 500)
}
})
},
fail(res) {
console.log("一键登录uni.preLogin失败", res)
if (res.errMsg != "login:ok") {
// 这里注意有个小坑: 不同运营商,返回的报错字段不同, 经过测试, 以下几乎包含了三大运营商报错字段
uni.showToast({
title: res.errMsg || res.metadata.resultMsg || res.metadata.error_data ||
res.metadata.resultDesc || "请检查是否插入有效sim卡及开启蜂窝数据网络",
icon: "none"
})
}
//如果手机没有插入有效的sim卡,或者手机蜂窝数据网络关闭,
//都有可能造成预登录校验失败。
}
})
}
}
}
</script>
<style>
</style>