本文详细讲解在uniapp中实现手机号一键登录的完整流程。涵盖前置条件、uniCloud环境配置、一键登录服务开通、云函数编写与部署,以及前端调用和后端URL化验证的实现。包含HBuilderX 3.4.0版本注意事项、常见错误码排查及access_token缺失问题的解决方案,帮助开发者快速集成该功能。
前置条件
- 手机必须安装SIM卡。
- 手机需开启数据流量功能。此操作与是否连接WiFi无关,不强制关闭WiFi,但数据流量通道必须保持启用状态。
- 需开通uniCloud服务,不过并不要求项目的所有后台代码都必须基于uniCloud开发。
创建uniapp项目并关联uniClound云空间
新建uniapp项目时,需勾选“启用uniClound”选项,并从中选择一个云服务商。

若要在已有项目中启用uniClound,可直接在项目文件夹上右键,选择“创建uniClound云开发环境”。

创建好uniClound云开发环境后,项目目录中会新增一个“uniClound”文件夹。右键该文件夹,选择“关联云服务空间或项目”。

若尚未创建相应的云服务空间,可选择新建云服务空间。

登录uniClound官网开发者后台,点击“新建服务空间”。

目前阿里云服务为免费状态,直接点击“立即购买”即可。

购买完成后,在前端再次刷新云服务空间列表,即可看到新购的服务空间,选中并关联即可。

开启一键登录模块并开通一键登录服务
打开项目的“manifest.json”文件,进入“App模块配置”,勾选“OAuth(登录授权)”模块。

在uniClound官网开发者后台开通一键登录服务,随后进入“账户信息”页面并完成充值。

余额充值

充值完成后,打开“应用管理”,点击“添加应用”。

填写应用相关信息后,点击“提交申请”。审核过程可能需要数小时。

若尚未获取Android包名,请按图示指引前往创建。

页面将跳转至应用列表,点击对应的应用名称进入详情页。

在详情页选择“Android云端证书”,并点击“创建证书”。

点击证书详情,记录“MD5”、“SHA1”和“SHA256”值。

点击“各平台信息”,将上述“MD5”、“SHA1”和“SHA256”等信息填入对应字段即可完成配置。

编写云函数并上传部署
返回项目目录,右键“cloundfunctions”,新建云函数或云对象,命名为“getPhoneNumber”(函数名可根据需求自定义)。

打开“getPhoneNumber”文件夹下的“index.js”文件,按如下代码进行编写。

复制下方代码,并将其中的DClound appid修改为应用自己的appid。
'use strict';
exports.main = async (event, context) => {
// event里包含着客户端提交的参数
let data = await uniCloud.getPhoneNumber({
appid: '__UNI__AAAAAA', // 替换成自己开通一键登录的应用的DCloud appid,使用callFunction方式调用时可以不传(会自动取当前客户端的appid),如果使用云函数URL化的方式访问必须传此参数
provider: 'univerify',
access_token: event.access_token,
openid: event.openid
})
return data//返回的data里包含手机号
}
自HBuilderX 3.4.0版本起,一键登录相关功能已移至扩展库uni-cloud-verify内。在过渡期内,无论开发者是否使用扩展库云函数,均可正常使用uniCloud.getPhoneNumber。但在HBuilderX 3.4.0及之后的版本中,若上传云函数时未指定使用uni-cloud-verify扩展库,将无法调用uniCloud.getPhoneNumber接口。
关于扩展库的详细说明请参考:云函数扩展库。
在云函数的package.json文件中添加uni-cloud-verify的引用即可启用此扩展,无需进行其他调整。完整的package.json示例如下:
{
"name": "univerify",
"extensions": {
"uni-cloud-verify": {} // 启用一键登录扩展,值为空对象即可
}
}
编写完成后,右键“cloudfunctions”,上传所有云函数以完成部署。

获取手机号流程

(第一种) 前端直接调用云函数获取手机号
此处演示一个简单的登录功能实现。
<template>
<view>
<button @tap="goLogin">手机号一键登录</button>
</view>
</template>
<script setup>
//手机号一键登录事件
function goLogin() {
uni.login({
provider: 'univerify',
univerifyStyle: { // 自定义登录框样式
//参考`univerifyStyle 数据结构`
"fullScreen": true, // 是否全屏显示,默认值: false
"title": '快速登录',
"backgroundColor": "#ffffff", // 授权页面背景颜色,默认值:#ffffff
"icon": {
"path": "../../static/my/头像.png" // 自定义显示在授权框中的logo,仅支持本地图片 默认显示App logo
},
"phoneNum": {
"color": "#000000", // 手机号文字颜色 默认值:#000000
"fontSize": "18" // 手机号字体大小 默认值:18
},
"slogan": {
"color": "#8a8b90", // slogan 字体颜色 默认值:#8a8b90
"fontSize": "12" // slogan 字体大小 默认值:12
},
// 一键登录
"authButton": {
"normalColor": "#3479f5", // 授权按钮正常状态背景颜色 默认值:#3479f5
"highlightColor": "#2861c5", // 授权按钮按下状态背景颜色 默认值:#2861c5(仅ios支持)
"disabledColor": "#73aaf5", // 授权按钮不可点击时背景颜色 默认值:#73aaf5(仅ios支持)
"textColor": "#ffffff", // 授权按钮文字颜色 默认值:#ffffff
"title": "本机号码一键登录" // 授权按钮文案 默认值:“本机号码一键登录”
},
// 其他登录方式
"otherLoginButton": {
"visible": "true", // 是否显示其他登录按钮,默认值:true
"normalColor": "#f8f8f8", // 其他登录按钮正常状态背景颜色 默认值:#f8f8f8
"highlightColor": "#dedede", // 其他登录按钮按下状态背景颜色 默认值:#dedede
"textColor": "#000000", // 其他登录按钮文字颜色 默认值:#000000
"title": "密码登录", // 其他登录方式按钮文字 默认值:“其他登录方式”
"borderWidth": "1px", // 边框宽度 默认值:1px(仅ios支持)
"borderColor": "#c5c5c5" //边框颜色 默认值: #c5c5c5(仅ios支持)
},
// 自定义按钮登录方式
"buttons": { // 仅全屏模式生效,配置页面下方按钮 (3.1.14+ 版本支持)
"iconWidth": "45px", // 图标宽度(高度等比例缩放) 默认值:45px
"list": [{
"provider": "apple",
"iconPath": "/static/test.jpg", // 图标路径仅支持本地图片
},
{
"provider": "weixin",
"iconPath": "/static/test.jpg",
}
]
},
"privacyTerms": {
"defaultCheckBoxState": "true", // 条款勾选框初始状态 默认值: true
"textColor": "#8a8b90", // 文字颜色 默认值:#8a8b90
"termsColor": "#1d4788", // 协议文字颜色 默认值: #1d4788
"prefix": "我已阅读并同意", // 条款前的文案 默认值:“我已阅读并同意”
"suffix": "并使用本机号码登录", // 条款后的文案 默认值:“并使用本机号码登录”
"fontSize": "12", // 字体大小 默认值:12,
"privacyItems": [
// 自定义协议条款,最大支持2个,需要同时设置url和title. 否则不生效
{
"url": "https://", // 点击跳转的协议详情页面
"title": "用户服务协议" // 协议名称
}
]
}
},
success(res) { // 登录成功
console.log(res);
let openid = res.authResult.openid; //拿到openid
let access_token = res.authResult.access_token; //拿到access_token
console.log(openid)
console.log(access_token)
// 在得到access_token和openid后,通过callfunction调用云函数
uniCloud.callFunction({
name: "getPhoneNumber",
data: {
openid,
access_token
}
}).then(res1 => {
console.log("获取成功");
console.log(res1);
// 获取用户的手机号
let phoneNumber = res1.result.phoneNumber;
//接下来就进行你自己的操作
//...
//...
}).catch((err) => {
// 执行失败后的操作
//...
//...
})
},
// 当用户点击自定义按钮时,会触发uni.login的fail回调[点击其他登录方式,可以跳转页面,或执行事件]
fail(res) { // 登录失败
console.log(res.code)
if (res.code == "30002") {
console.log('账号密码登录');
}
}
})
}
</script>
(第三种)后台调用云函数获取手机号
后台代码
// 以nodejs为例
const crypto = require('crypto')
const secret = 'your-secret-string' // 自己的密钥不要直接使用示例值,且注意不要泄露
const hmac = crypto.createHmac('sha256', secret);
// 自有服务器生成签名,并以GET方式发送请求
const params = {
access_token: 'xxx', // 客户端传到自己服务器的参数
openid: 'xxx'
}
// 字母顺序排序后拼接签名串
const signStr = Object.keys(params).sort().map(key => {
return `${key}=${params[key]}`
}).join('&')
hmac.update(signStr);
const sign = hmac.digest('hex')
// 最终请求如下链接,其中https://xxxx/xxx为云函数Url化地址
// https://xxxx/xxx?access_token=xxx&openid=xxx&sign=${sign} 其中${sign}为上一步得到的sign值云函数Url化地址设置可根据实际需求进行修改。


对应云函数“index.js”,需按如下方式修改代码。
// 云函数验证签名,此示例中以接受GET请求为例作演示
const crypto = require('crypto')
exports.main = async function (event){
const secret = 'your-secret-string' // 自己的密钥不要直接使用示例值,且注意不要泄露
const hmac = crypto.createHmac('sha256', secret);
let params = event.queryStringParameters
const sign = params.sign
delete params.sign
const signStr = Object.keys(params).sort().map(key => {
return `${key}=${params[key]}`
}).join('&')
hmac.update(signStr);
if(sign!==hmac.digest('hex')){
throw new Error('非法访问')
}
const {
access_token,
openid
} = params
const res = await uniCloud.getPhoneNumber({
provider: 'univerify',
appid: 'xxx', // DCloud appid
access_token: event.queryStringParameters.access_token,
openid: event.queryStringParameters.openid
})
// 返回手机号给自己服务器
return res
}注意:云函数代码修改后,必须右键“getPhoneNumber”并选择“上传部署”才能生效。
前端代码:
uni.login({
provider: 'univerify',
success: function(res) {
console.log('LOGINres----', res);
let data = {
accessToken: res.authResult.access_token,
openId: res.authResult.openid
}
console.log('data----', data);
uni.request({
url: 'https://xxxxx/xxx', //自己应用服务器的请求地址
data: {
data: JSON.stringify(data)
},
method: "POST",
header: {
"content-type": "application/x-www-form-urlencoded"
},
success: function(r) {
console.log('结果---', r)
//获取登录成功的token,并保存在前端
},
fail: function(err) {
console.log('err--', err);
}
})
},
fail: function(err) {
console.log('err', err);
}
})
错误码

30004
login:fail -20102其他错误 Android端排查: 1.确认开发者中心已添加应用且一键登录功能审核通过。 2.检查开通一键登录时使用的签名证书与云打包时使用的签名证书是否一致。
常见问题
- 后台请求云函数获取手机号报错:Error: Parameter access_token is required(1)首先检查后端代码中是否传递了access_token参数。
(2)检查前端云函数的“index.js”文件中获取openid和access_token的方式,需增加对“queryStringParameters”的处理。并确保修改“index.js”文件后,右键执行“上传部署”操作使更改生效。
参考:
1.官网文档:https://uniapp.dcloud.net.cn/univerify.html
总结
本文介绍了uniapp手机号一键登录的实现方法。如需了解更多uniapp手机号一键登录相关内容,建议搜索本站历史文章或继续浏览后续文章,感谢大家的支持!