方法一:通过云函数getPhoneNumber方法
注意:只针对非个人开发者,且完成了认证的小程序开放
1.1 小程序页面通过button元素获取用户授权
<button @getphonenumber="getphonenumber" open-type="getPhoneNumber"></button>
async getphonenumber(e) {
const errMsg = e.detail.errMsg
if (errMsg === "getPhoneNumber:ok") {
// 调用云函数
const cloudRes = await wx.cloud.callFunction({
name: 'getPhone' // 自己创建的云函数名称
data: {
code: e.detail.code
}
})
}
}
1.2 调用云函数获取手机号
index.js
const cloud = require('wx-server-sdk');
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV,
});
exports.main = async (event, context) => {
const { code } = event;
if (!code) {
throw new Error('缺少参数code');
}
const result = await cloud.openapi.phonenumber.getPhoneNumber({
code: code,
});
return result;
};
配置接口权限 config.json
{
"permissions": {
"openapi": [
"phonenumber.getPhoneNumber"
]
}
}
方法二:后台自行解析
2.1 获取用户授权,调用wx.login登录
<button @getphonenumber="getphonenumber" open-type="getPhoneNumber"></button>
async getphonenumber(e) {
const errMsg = e.detail.errMsg
if (errMsg === "getPhoneNumber:ok") {
uni.login({
provider: 'weixin',
success: async (res) => {
const cloudFunRes = await wx.cloud.callFunction({
name: "getPhone", // 自己创建的云函数名称
js_code: res.code,
encryptedData: e.detail.encryptedData,
iv: e.detail.iv
})
})
})
}
}
调用云函数解析获取手机号
const cloud = require('wx-server-sdk');
const axios = require("axios")
const CryptoJS = require('crypto-js') ;
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV,
});
const appid = "小程序appid"
const secret = "小程序密钥"
async function getSession_key(js_code) {
const res = await axios.get(`https://api.weixin.qq.com/sns/jscode2session?appid=${appid}&secret=${secret}&js_code=${js_code}&grant_type=authorization_code`)
return res.data.session_key
}
class WXBizDataCrypt {
constructor(appId, sessionKey) {
this.appId = appId;
this.sessionKey = sessionKey;
}
decryptData(encryptedData, iv) {
// 确保 encryptedData 和 iv 都是 Base64 编码的字符串
const sessionKey = CryptoJS.enc.Base64.parse(this.sessionKey);
const encryptedBuffer = CryptoJS.enc.Base64.parse(encryptedData);
const ivBuffer = CryptoJS.enc.Base64.parse(iv);
try {
// 使用 AES 解密
const decrypted = CryptoJS.AES.decrypt(
{ ciphertext: encryptedBuffer },
sessionKey,
{
iv: ivBuffer,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
}
);
// 将解密后的数据转换为 UTF-8 字符串
const decoded = decrypted.toString(CryptoJS.enc.Utf8);
// 解析 JSON 数据
const result = JSON.parse(decoded);
// 检查解密结果中的 App ID
if (result.watermark.appid !== this.appId) {
throw new Error('Illegal Buffer: App ID mismatch');
}
return result;
} catch (err) {
console.error('解密失败', err);
throw new Error('Illegal Buffer: ' + err.message);
}
}
}
exports.main = async (event, context) => {
const { js_code, encryptedData, iv } = event;
const session_key = await getSession_key(js_code)
if(session_key) {
let pc = new WXBizDataCrypt(appid, session_key);
try {
let data = pc.decryptData(encryptedData, iv);
return {
code: 1,
data
}
} catch (err) {
return {
code: -1,
msg: '获取失败'
}
}
} else {
return {
code: -1,
msg: '获取失败'
}
}
};