获取微信手机号
获取手机号的按钮
<!-- 用户展示手机号,无法输入 --> <uni-easyinput class="input disabled-input-click" placeholder="清输入手机号" v-model.trim="formData.phone" disabled /> <!-- open-type:开放能力 是配合某些事件的,比如 @getphonenumber:获取用户手机号回调,使用这个函数的前提是 open-type="getPhoneNumber" @getphonenumber:微信、支付宝、百度、抖音、快手、京东小程序、小红书小程序 --> <button size="mini" open-type="getPhoneNumber" @getphonenumber="getPhone">获取手机号</button>点击按钮的时候,会先出现一个弹窗。这个时候还没有触发
getPhone方法。无论点击Cancel还是Authorize都会触发getPhone方法
点击
Cancel时,组件传递的值:
点击
Authorize组件传递的值:
上面的整个流程是这样的
// 1. 开发者只定义了按钮 <button open-type="getPhoneNumber" @getphonenumber="getPhone"> 获取手机号 </button> // 2. 用户点击按钮 // ↓ // 3. 微信客户端检测到 open-type="getPhoneNumber" // ↓ // 4. 微信客户端检查权限: // - 小程序是否有权限请求手机号(企业认证) // - 用户是否已登录微信 // - 用户是否之前拒绝过授权 // ↓ // 5. 微信客户端在系统层渲染弹窗 // ↓ // 6. 用户操作弹窗: // - 点击"允许" → 生成code,回调 getPhone 并传入 code // - 点击"拒绝" → 生成错误信息,回调 getPhone 并传入错误 // ↓ // 7. 你的 getPhone 方法被执行这个弹窗是微信App内置的系统级授权弹窗,由微信客户端直接渲染和控制,不是小程序前端代码可以模拟或自定义的。
code 是由微信客户端生成的:当用户点击
<button open-type="getPhoneNumber">并授权后,微信客户端(微信App本身)会在本地生成一个临时的、一次性的授权凭证(code),并通过@getphonenumber回调返回给你的前端。getPhone(e) { const code = e.detail.code; // 这是微信客户端生成的临时凭证 }这个 code 实际上是一个加密的授权票据,包含了:
- 用户的身份信息(openId 的加密映射)
- 授权时间戳
- 授权范围(获取手机号)
- 小程序的 AppID
这个 code 具有以下特性:
- 时效性:通常有效期为5分钟
- 一次性:使用后立即失效
- 绑定性:与特定小程序、特定用户、特定授权绑定
前端
getPhone代码,调用后端,传入e.detail.code获取电话号码。不能在前端直接获取,因为需要用到appid和secret,在前端获取不安全。const toolsCloudObj = uniCloud.importObject('public-tools', {customUI: true}); const getPhone = async (e) => { try { console.log(e.detail); showLoading({ title: '获取中', mask: true }); // 使用解构赋值 let {data:{phone_info:{phoneNumber}}} = await toolsCloudObj.phone({ code: e.detail.code }); formData.value.phone = phoneNumber; } finally { hideLoading(); } };后端获取电话的代码:
//unicloud云对象内的phone方法,params是客户端传来的值 async phone(params){ //调用微信凭证接口,获取access_token,传入appid和secret //在这里可以判断是否已经有access_token缓存,如果没有再去调用凭证接口,避免重复调用 let {data:{access_token}} = await uniCloud.request({ url:"https://api.weixin.qq.com/cgi-bin/token", data:{ grant_type:"client_credential", // 填写 client_credential appid:"w...................5", // 账号的唯一凭证,即 AppID secret:"5c......................................43" //唯一凭证密钥,即 AppSecret } }) let res = await uniCloud.request({ url:"https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token="+access_token, method:"POST", data:{ code:params.code } }) return res; }https://api.weixin.qq.com/cgi-bin/token:获取接口调用凭据。本接口用于获取获取全局唯一后台接口调用凭据(Access Token),token 有效期为 7200 秒。(getAccessToken)access_token是微信服务端颁发给小程序的接口调用凭证,类似于一把”钥匙”或”通行证”。微信服务端需要验证”你是谁”,但又不能让前端直接使用AppSecret(密钥),因此设计了access_token机制。为的是证明调用接口的是合法的小程序,而不是恶意攻击者。- 返回参数
access_token:获取到的凭证expires_in:凭证有效时间,单位:秒。目前是7200秒之内的值。
- 在access_token 使用说明里面,建议开发者使用中控服务器统一获取和刷新access_token,其他业务逻辑服务器所使用的access_token 均来自于该中控服务器,不应该各自去刷新,否则容易造成冲突,导致access_token覆盖而影响业务。
- 在Java中应该是可以统一放在缓存里面,或者服务器文件
https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token="+access_token该接口用于将code换取用户手机号。 说明,每个code只能使用一次,code的有效期为5min。
查询参数:access_token,接口调用凭证
请求体:code,由微信客户端生
返回参数:
{ "statusCode": 200, "header": { "connection": "keep-alive", "content-type": "application/json; charset=UTF-8", "content-length": "187" }, "data": { "errcode": 0, "errmsg": "ok", "phone_info": { "phoneNumber": "1..........7", "purePhoneNumber": "1..........7", "countryCode": "86", "watermark": { "timestamp": 1774245023, "appid": "w....................5" } } } }