uniapp 微信小程序 手机号快速验证组件 解密 encryptedData 获取手机号
手机号快速验证组件
该能力旨在帮助开发者向用户发起手机号申请,并且必须经过用户同意后,开发者才可获得由平台验证后的手机号,进而为用户提供相应服务。 以下是旧版本组件使用指南,注意使用旧版本组件时,需先调用wx.login接口。建议开发者使用新版本组件,以增强小程序安全性。详情新版组件使用指南。 因为需要用户主动触发才能发起手机号快速验证,所以该功能不由 API 来调用,需用 button 组件的点击来触发。
使用方法
需要将
button
组件open-type
的值设置为getPhoneNumber
,当用户点击并同意之后,可以通过bindgetphonenumber
事件回调获取到微信服务器返回的加密数据, 然后在第三方服务端结合session_key
以及app_id
进行解密获取手机号。
注意事项
在回调中调用
wx.login
登录,可能会刷新登录态。此时服务器使用code
换取的sessionKey
不是加密时使用的sessionKey
,导致解密失败。建议开发者提前进行login
;或者在回调中先使用checkSession
进行登录态检查,避免login
刷新登录态。
uniapp代码示例
注意原生的写法不一样
html
<button class="list-btn" open-type="getPhoneNumber" @getphonenumber="decryptPhoneNumber">立即购买</button>
接下来就是解密
第一步:
安装 crypto-js
bash
pnpm install crypto-js
第二步:
新建WXBizDataCrypt.ts
文件 创建 WXBizDataCrypt
类 :用于解密 encryptedData
。
ts
import CryptoJS from 'crypto-js';
export class WXBizDataCrypt {
private appId: string;
private sessionKey: string;
constructor(appId: string, sessionKey: string) {
this.appId = appId;
this.sessionKey = sessionKey;
}
decryptData(encryptedData: string, iv: string) {
// base64 decode
const sessionKey = CryptoJS.enc.Base64.parse(this.sessionKey);
const encryptedDataBuffer = CryptoJS.enc.Base64.parse(encryptedData);
const ivBuffer = CryptoJS.enc.Base64.parse(iv);
try {
// 解密
const cipherParams = CryptoJS.lib.CipherParams.create({
ciphertext: encryptedDataBuffer
});
const decipher = CryptoJS.AES.decrypt(cipherParams, sessionKey, {
iv: ivBuffer,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
const decoded = decipher.toString(CryptoJS.enc.Utf8);
const decodedData = JSON.parse(decoded);
if (decodedData.watermark.appid !== this.appId) {
throw new Error('Invalid appId');
}
return decodedData;
} catch (err) {
throw new Error('Decrypt failed');
}
}
}
第三步:
在需要解密的页面中引入 WXBizDataCrypt
类,并使用 decryptData
方法解密 encryptedData
。
ts
import { WXBizDataCrypt } from '../../utils/WXBizDataCrypt';
ts
const decryptPhoneNumber = (e: any) => {
const { encryptedData, iv } = e.detail;
const appId = 'your_app_id';
const sessionKey = 'your_session_key';
const wxBizDataCrypt = new WXBizDataCrypt(appId, sessionKey);
const decryptedData = wxBizDataCrypt.decryptData(encryptedData, iv);
console.log('Decrypted data:', decryptedData);
}