小程序获取微信运动步数 本地解密

小程序获取微信运动步数

最近有个需求需要在小程序获取到微信的运动步数

看了一下微信的官方文档有个内置api可以用

wx.getWeRunData(Object object)

但是获取到的信息是加密的,需要解密后才能使用

细看文档官方给了四种不同语言的方法

这里我们使用Node,在前端本地进行解密

先看看官方的demo

javascript 复制代码
//demo.js

var WXBizDataCrypt = require('./WXBizDataCrypt')

var appId = 'wx4f4bc4dec97d474b'
var sessionKey = 'tiihtNczf5v6AKRyjwEUhQ=='
var encryptedData = 
	'CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZM'+
	'QmRzooG2xrDcvSnxIMXFufNstNGTyaGS'+
	'9uT5geRa0W4oTOb1WT7fJlAC+oNPdbB+'+
	'3hVbJSRgv+4lGOETKUQz6OYStslQ142d'+
	'NCuabNPGBzlooOmB231qMM85d2/fV6Ch'+
	'evvXvQP8Hkue1poOFtnEtpyxVLW1zAo6'+
	'/1Xx1COxFvrc2d7UL/lmHInNlxuacJXw'+
	'u0fjpXfz/YqYzBIBzD6WUfTIF9GRHpOn'+
	'/Hz7saL8xz+W//FRAUid1OksQaQx4CMs'+
	'8LOddcQhULW4ucetDf96JcR3g0gfRK4P'+
	'C7E/r7Z6xNrXd2UIeorGj5Ef7b1pJAYB'+
	'6Y5anaHqZ9J6nKEBvB4DnNLIVWSgARns'+
	'/8wR2SiRS7MNACwTyrGvt9ts8p12PKFd'+
	'lqYTopNHR1Vf7XjfhQlVsAJdNiKdYmYV'+
	'oKlaRv85IfVunYzO0IKXsyl7JCUjCpoG'+
	'20f0a04COwfneQAGGwd5oa+T8yO5hzuy'+
	'Db/XcxxmK01EpqOyuxINew=='
var iv = 'r7BXXKkLb8qrSNn05n0qiA=='

var pc = new WXBizDataCrypt(appId, sessionKey)

var data = pc.decryptData(encryptedData , iv)

console.log('解密后 data: ', data)
// 解密后的数据为
//
// data = {
//   "nickName": "Band",
//   "gender": 1,
//   "language": "zh_CN",
//   "city": "Guangzhou",
//   "province": "Guangdong",
//   "country": "CN",
//   "avatarUrl": "http://wx.qlogo.cn/mmopen/vi_32/aSKcBBPpibyKNicHNTMM0qJVh8Kjgiak2AHWr8MHM4WgMEm7GFhsf8OYrySdbvAMvTsw3mo8ibKicsnfN5pRjl1p8HQ/0",
//   "unionId": "ocMvos6NjeKLIBqg5Mr9QjxrP1FA",
//   "watermark": {
//     "timestamp": 1477314187,
//     "appid": "wx4f4bc4dec97d474b"
//   }
// }
javascript 复制代码
//WXBizDataCrypt.js

var crypto = require('crypto')

function WXBizDataCrypt(appId, sessionKey) {
  this.appId = appId
  this.sessionKey = sessionKey
}

WXBizDataCrypt.prototype.decryptData = function (encryptedData, iv) {
  // base64 decode
  var sessionKey = new Buffer(this.sessionKey, 'base64')
  encryptedData = new Buffer(encryptedData, 'base64')
  iv = new Buffer(iv, 'base64')

  try {
     // 解密
    var decipher = crypto.createDecipheriv('aes-128-cbc', sessionKey, iv)
    // 设置自动 padding 为 true,删除填充补位
    decipher.setAutoPadding(true)
    var decoded = decipher.update(encryptedData, 'binary', 'utf8')
    decoded += decipher.final('utf8')
    
    decoded = JSON.parse(decoded)

  } catch (err) {
    throw new Error('Illegal Buffer')
  }

  if (decoded.watermark.appid !== this.appId) {
    throw new Error('Illegal Buffer')
  }

  return decoded
}

module.exports = WXBizDataCrypt

乍一看,官方的例子好像还行,但是用起来...不必多说

开始踩坑
问题1.将WXBizDataCrypt.js放入本地的utils后,马上报错找不到crypto

遂查之

原因是微信小程序的前端环境中不支持 Node.js 的 crypto 模块 ,因为 crypto 是 Node.js 的内置模块,主要用于服务器端的加密操作,而微信小程序运行在客户端,无法直接使用 Node.js 的模块

气煞我也

怒改之

  • 使用 npm install crypto-js --save 将crypto-js下载到node_modules
  • 找到 node_modules\crypto-js\crypto-js.js 将crypto-js.js复制到utils
  • 将WXBizDataCrypt.js文件中的 var crypto = require('crypto') 替换为 const CryptoJS = require('crypto-js');

over,再跑一下

问题2.WXBizDataCrypt.js文件中Buffer不存在

遂查之

原因是Buffer 是 Node.js 中的一个核心模块,用于处理二进制数据。然而,微信小程序的前端环境并不支持 Node.js 的 Buffer 模块,因为它是基于浏览器环境的

怒喷之 (我***)

怒改之

  • 使用 CryptoJS 的 Base64 解码

    javascript 复制代码
    const sessionKeyBuffer = CryptoJS.enc.Base64.parse(this.sessionKey);
    const encryptedDataBuffer = CryptoJS.enc.Base64.parse(encryptedData);
    const ivBuffer = CryptoJS.enc.Base64.parse(iv);
最终代码 WXBizDataCrypt.js
javascript 复制代码
const CryptoJS = require('crypto-js');

function WXBizDataCrypt(appId, sessionKey) {
  this.appId = appId;
  this.sessionKey = sessionKey;
}

WXBizDataCrypt.prototype.decryptData = function (encryptedData, iv) {
  // 使用 CryptoJS 的 Base64 解码
  const sessionKeyBuffer = CryptoJS.enc.Base64.parse(this.sessionKey);
  const encryptedDataBuffer = CryptoJS.enc.Base64.parse(encryptedData);
  const ivBuffer = CryptoJS.enc.Base64.parse(iv);

  try {
    // 解密操作
    const decrypted = CryptoJS.AES.decrypt(
      { ciphertext: encryptedDataBuffer },
      sessionKeyBuffer,
      {
        iv: ivBuffer,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
      }
    );

    // 将解密后的数据转换为字符串
    const decryptedText = decrypted.toString(CryptoJS.enc.Utf8);

    // 将字符串解析为 JSON 对象
    const decryptedData = JSON.parse(decryptedText);

    // 校验 appid
    if (decryptedData.watermark.appid !== this.appId) {
      throw new Error('Invalid appid');
    }

    return decryptedData;
  } catch (err) {
    console.error('解密失败:', err);
    throw new Error('Illegal Buffer');
  }
}

module.exports = WXBizDataCrypt;
小程序中使用
javascript 复制代码
wx.getWeRunData({
      success: (res) => {
        console.log("getWeRunData>>>",res)
        // code: loginRes.code,
        const encryptedData = res.encryptedData
        const iv = res.iv
        const appId = "*********"	//自取
        const sessionKey = "*********"	//自取
        var pc = new WXBizDataCrypt(appId, sessionKey)

        var data = pc.decryptData(encryptedData , iv)

        console.log('解密后 data: ', data)
      }
    });
相关推荐
咖啡の猫16 小时前
微信小程序案例 - 自定义 tabBar
微信小程序·小程序·notepad++
咖啡の猫16 小时前
微信小程序全局数据共享
微信小程序·小程序
桐溪漂流16 小时前
微信小程序cli脚本预览上传
微信小程序·小程序
咖啡の猫16 小时前
微信小程序使用 npm 包
微信小程序·小程序·npm
东东5161 天前
xxx食堂移动预约点餐系统 (springboot+微信小程序)
spring boot·微信小程序·小程序·毕业设计·个人开发·毕设
韩立学长2 天前
【开题答辩实录分享】以《智慧校园平台微信小程序》为例进行选题答辩实录分享
spring boot·微信小程序·小程序
h_65432102 天前
微信小程序:按顺序一张图片加载完后,再加载另一张
微信小程序·小程序
qq_316837753 天前
uniapp打包微信小程序使用插件
微信小程序·小程序·uni-app
不爱学习小趴菜4 天前
uniapp微信小程序无法屏蔽右上角胶囊按钮(...)问题解决方案
微信小程序·小程序·uni-app
plmm烟酒僧4 天前
《微信小程序demo开发》第一部分-编写页面逻辑
javascript·微信小程序·小程序·html·微信开发者工具·小程序开发