在前一文章我讲了如何通过php后端解密encryptedData获得过去三十一天微信运动步数,这对于已有自己服务器者来说是个不错的选择,在服务器上需要进行十分复杂的配置,但如果仅为了实现这一个功能,去租用服务器,显然成本太高,微信小程序开发工具本身就为提供了更“轻”成本的方案——nodejs云函数。要运行云函数,要安装nodejs,百度十分容易搜索到,如果在开始本文前你还没有接触过云函数,请自行阅读官方小程序开发文档,云函数是微信小程序开发的一个重要内容且并不难学,有编程基础的人最多半天就可入门。
好了,正式开讲。
微信小程序通过wx.getWeRunData获得用户过去三十一天微信运动步数,获取成功后,会得到一个叫encryptedData的参数,它对将用户涉及用户隐私的信息进行了加密,如此处的微信步数,需要通过后端解密,才能得到有用信息,encryptedData的解密算法可参考官方文档https://developers.weixin.qq.com/minigame/dev/guide/open-ability/signature.html#加密数据解密算法。官方文档还提供示例代码https://res.wx.qq.com/wxdoc/dist/assets/media/aes-sample.eae1f364.zip下载。下载后得到一个压缩包,解压后里面有C++、Node、php、Python四种语言的后端语言示例代码,这里用Nodej.js用后端来解密数据。下面就对nodejs后端来解密微信步数数据。
首先,你得有一个正式appid,然后在这个appid下请申请一个密钥secret,测试账号是不能用于云开发的。
有了appid和secret,我们就可以新建项目了,打开开发工具,新建项目,这里选择云开发基础模板,可以看到开发工具已经为我们生成了一个quickstartFunctions的云函数,为了检测我们的含有云函数的小程序是否配置正确,可以将quickstartFunctions上传,然后任意测试一个官方的例程,比如获得openid,如果能正确输出结果,就说明我们配置是正确的,可以下一步了。
接下来就可以新建一个获得微信步数的云函数,在云函数根目录中新建一个文件夹,这里取名getrundata,在此文件下新建一个nodejs云函数,然后将WXBizDataCrypt.js文件也复制到这个目录下备用。
我们先将官方demo打开,将代码复制到刚建立的云函数中,可以看到解密需要encryptedData、iv和sessionKey,官方示例是静态的变量,我们要将它们换成“动态的”。encryptedData、iv可以通过wx.getWeRunData获得,sessionKey要复杂,我们先执行wx.login来获得res.code,然后来访问https://api.weixin.qq.com来获得,这里需要注意的是这个访问此地址也要在后端,在此处即nodejs,因为里面要提供你的appid和secret,前端容易反编译,那么你appid和secret便暴露了,具体说明可查看https://kf.qq.com/faq/1706236NjINj1706236VRZBR.html。
因此将云函数代码修改如下,保存上传云函数getrundata。
const cloud = require('wx-server-sdk');
const WXBizDataCrypt = require('./WXBizDataCrypt')
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
});
// 获取openId云函数入口函数
exports.main = async (event, context) => {
// 获取基础信息
const wxContext = cloud.getWXContext();
var appid = "你的appid";
var secret = "你的secret";
var rescode=event.rescode;
var encryptedData=event.encryptedData;
var iv=event.iv;
var sessionKey = ''
const axios = require('axios');
var strout=""
// 设置API的URL
const url = 'https://api.weixin.qq.com/sns/jscode2session?appid=' + appid + '&secret=' + secret + '&js_code=' +rescode + '&grant_type=authorization_code';
// 发送GET请求
await
axios.get(url)
.then(response => {
console.log('Response:', response.data);
strout=response.data;
})
.catch(error => {
console.error('Error:', error);
strout=error
});
sessionKey=strout.session_key
console.log(sessionKey)
var pc = new WXBizDataCrypt(appid, sessionKey)
var data = pc.decryptData(encryptedData , iv)
//console.log(encryptedData)
return data
};
等待上传完成后,就可以编写前端代码,将除index以外的page全部删除,相应的app.json中index以外配置路径已删除,再将index对应的wxml、json、wxss和js的代码也全部删除,接着修改js代码如下
// pages/index/index.js
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
},
getrundata()
{
var that=this;
wx.login({
success: function (res) {
var encryptedData="";
var iv=""
if (res.code)
{
var rescode=res.code
wx.getWeRunData({
success: function (res) {
console.log("wx.getWeRunData成功")
console.log(res);
encryptedData = res.encryptedData;
iv = res.iv;
that.connnodejs(rescode,encryptedData,iv)
},
})
}
}
})
},
connnodejs(rescode,encryptedData,iv)
{
var that=this;
wx.cloud.callFunction({
name: 'yincloud',
config: {
env: this.data.envId
},
data: {
childfunc: 'getencryptedData',
rescode:rescode,
encryptedData:encryptedData,
iv:iv
}
}).then((resp) =>
{
console.log(resp.result)
that.setData(
{
steplist:resp.result.stepInfoList
}
)
}).catch((e) => {
console.log(e)
});
}
})
再编写wxml代码,如下
<!--pages/index/index.wxml-->
<wxs module="m1">
var ts2date=function(timestamp)
{
//timestamp默认是1970-1-1加timestamp毫秒,这里秒,所以*1000
var date = getDate(timestamp*1000);
var year = date.getFullYear();
var month = ('0' + (date.getMonth() + 1)).slice(-2);
var day = ('0' + date.getDate()).slice(-2);
var hours = ('0' + date.getHours()).slice(-2);
var minutes = ('0' + date.getMinutes()).slice(-2);
var seconds = ('0' + date.getSeconds()).slice(-2);
//const formattedDate = year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;
var formattedDate = year + '-' + month + '-' + day ;
return formattedDate;
//return "fdsf";
}
module.exports.ts2date=ts2date;
</wxs>
<button type="warn" plain="true" bind:tap="getrundata">获取微信步数</button>
<view wx:for="{{steplist}}"> {{m1.ts2date(item.timestamp)}} {{item.step}}步</view>
运行代码,如图1,代码运行成功。如果没有看到输出运动步数列表,可以在用console.log输出关键变量,查看哪个变量出错,云函数查看日志输出的方法与前端日志输出的方法是不同的,云函数查看日志的办法在云根目录或某个函数目录下右键开启云函数本地调试,在弹出窗口下勾选开启本地调试并切换到console标签,此时再去运行代码,就能看到日志输出了。如图2为运行正确的日志输出结果。
图1
图2
整组代码我们要还要注意两点,一是请将appid、secret和云函数的环境变量替换成你自己的,二是通过上面nodejs代码能看到访问api.weixin.qq.com需要,appid、secret、js_code,js_code就是wx.login成功后获得的res.code,这里的res.code是一次性,即每次访问api.weixin.qq.com,都要重新wx.login一次,如果同一res.code多次api端会返回一个错误代码。
好了,整个代码完成,只要你学习了云函数的基础,是不是比用php后端解密更简单,另外由于云函数(上传后)已运行于腾讯的云端,因此可在真机上也能运行,而前文通过php解密,需要申请域名、服务器,然后在微信公众平台添加申请的域名才能在真机运行,php端运行于本地电脑,真机是无法运行的,只能在开发工具的模拟上运行。源码如下。https://download.csdn.net/download/wstcl/89232327?spm=1001.2014.3001.5503。 over