小程序需要用到用户的手机号码,看了下API 以及相关的demo,基本都是服务端进行解密的,问题是需要的参数并没有用到secret,只需要 session_key / iv /encryptedData 即可,那完全可以在客户端进行处理啊。
想到这个问题的肯定不止我一个,动手能力强的也超级多...开动起来吧,直接百度试试水,竟然找到了.. 不过直接按照他的拿来还有报错(有几个引入问题),注释后就OK了。
准备
- cryptoJs
- 一个解密函数,可直接参考官网nodejs demo。
代码
WXDataEncryp.js
var Crypto = require('../utils/encry/cryptojs.js').Crypto;
function WXDataEncryp(appId, sessionKey) {
this.appId = appId
this.sessionKey = sessionKey
}
WXDataEncryp.prototype.decryptData = function (encryptedData, iv) {
// base64 decode :使用 CryptoJS 中 Crypto.util.base64ToBytes()进行 base64解码
var encryptedData = Crypto.util.base64ToBytes(encryptedData)
var key = Crypto.util.base64ToBytes(this.sessionKey);
var iv = Crypto.util.base64ToBytes(iv);
// 对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充
var mode = new Crypto.mode.CBC(Crypto.pad.pkcs7);
try {
// 解密
var bytes = Crypto.AES.decrypt(encryptedData, key, {
asBpytes:true,
iv: iv,
mode: mode
});
var decryptResult = JSON.parse(bytes);
} catch (err) {
console.log(err)
}
return decryptResult
}
module.exports = WXDataEncryp;
将cryptoJs
下载后扔到项目下,修改cryptojs.js
,如下:
使用
直接引入,传参即可。
xxx.js
//引入
const WXDataEncryp = require('../../utils/WXDataEncryp');
...
//获取手机号码按钮点击回调
async getPhoneNumber(e){
if(e.detail.iv && e.detail.encryptedData){
let data = e.detail.encryptedData;
let iv = e.detail.iv;
//此处获取 appid session_key
let appId = config.appid;
let userInfo = await util.getStoreInfo();
let sessionKey = userInfo.session_key;
let datains = new WXDataEncryp(appId,sessionKey);
let rs = datains.decryptData(data,iv)
//将手机号码进行存储到userInfo中
console.log(rs.phoneNumber);//获得手机号
}else{
util.msg('获取授权失败')
}
}
拿到手机号进行回传server 进行保存即可,后续再需要就可以直接跟server要了。