微信小程序通过php后端显示(解密)微信步数

今天来讲一下微信小程序如何获得微信运动步数,并通过后端php解密。
  微信小程序通过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四种语言的后端语言示例代码,这里用php用后端来解密数据。下面就对php用后端来解密微信步数数据。为了方便理解我将整个过程切割成几大块。以下讲解都是基于win10 64位讲解。
  第一块内容是安装配置php程序,这里需要你的php版本为7.0及以上,如果是7.0以下建议卸载,原因后面会讲。到php官网下载php,解压放到磁盘上,我下载的就php8,php8需要 VC++2019支持,解压路径中不要有空格和非英文字符。
  在这里插入图片描述
  图1
  在这里插入图片描述
图2

接下来配置环境变量,右键此电脑,属性,如图1界面,选择高级系统设置,弹出系统属性窗口如图2点击环境变量按钮,出现环境变量窗口,在系统变量窗格中如图3,找到path对其编辑,没有自己建一个,弹出编辑环境变量窗口如图4,新建一个变量,将刚下载的php根路径填入。保存
  在这里插入图片描述
  图3
  在这里插入图片描述
图4

最后,打开命令窗口输入php -v,如果能看到php的版本信息,说明php安装完成了。
  第二块内容是如何添加iis信息服务,虽然Appace可以运行php,但我配不好,或许版本高吧,所以选择了IIS,如果你的Appace能成功运行php8页面在或者已经配好iis可跳过此步。
  在这里插入图片描述
  图5
  在这里插入图片描述
  图6

首先,打开控制面板,点击程序 卸载程序(图5),进入后可以看到如图6界面,再选择启用或关闭windows功能,进入如图7界面将Internet information services节点下下web管理功能、万维网功能相应选项勾上,如果不知道哪些需要选择,全部勾上也无妨。点击确定后,等其进度全部后重启计算机。
  在这里插入图片描述
  图7

重启后,在桌面右键此电脑图标,在弹出菜单中选择管理后可以看到在计算机管理界面服务和应用程序节点已经有了Internet information services,说明我们已经安装了IIS,将其选择,可以看到一个网站节点如图8,右键添加网站,如图9,根据实际情况填写红框中的内容,然后确定。这样我们就建立了一个站点。
  在这里插入图片描述
  图8
  在这里插入图片描述
  图9

第三块,让php演示代码正常运行。首先,选择我们刚建立站点节点,如图10,点击处理程序映射,在处理程序映射界面,右键,选择添加模块映射,按图10填写,注意可执行文件要替换你自己的路径。确定。
  在这里插入图片描述
图10
  接着找到从微信公众平台下载好的后端语言示例代码,将php整目录复制到刚新建站点目录下,展开站点节点,我们可以看到多了一个php目录,打开php目录,新建一个index.php。在index.php中添加如下代码,保存。在浏览器输入地址,如http://localhost/PHP/index.php,应可以看到图11信息,说明iis成功运行了php。
  在这里插入图片描述
  图11

 文件内容如下:
 
<?php 
  phpinfo();
?>

在这里插入图片描述
图12
  这时,你是不是已经非常激动在浏览器打开demo.php页面,但是你却看到如下界面,如图12,这是因类需要openssl来完成解密,并且只有php7及以上才支持openssl,这也前面为什么要卸载低版本php的原因。再回到index.php运行界面,再来看图11红框中的内容,可以看到Loaded Configuration File中为none,这说明我们php8目录没有php.ini配置文件,我们暂时搁置php.ini先来先下载安装opessl。打开地址:https://slproweb.com/products/Win32OpenSSL.html,下载合适版本,我这里下载light版本,下载并安装,之后,我们再去配置环境变量,将openssl安装路径添加到path中。装完openssl,去配置php.ini,编辑php.ini,配置如下
extension=php_openssl.dll

extension_dir = “你的php程序路径\ext”
  保存,重启iis。再在浏览器访问index.php页面,如图13,Loaded Configuration File已经有了php.ini,还多出一个openssl的内容(图13为拼图,可以在网页上搜一下openssl),此时打开demo.php后端完成了encryptedData的解密。如图与官网示例解密内容一致。下面对官方的demo.php进行修改(注意:解密时有一个变量sessionkey,需要访问微信api解码,此过程应在后端完成,访问微信api是不允许在前端进行的,在发布小程序时,应将需要需要访问的域名放到白名单中,而微信官方禁止微信api放到白名单中,因为访问需要你的appid和秘钥secret,二者可在微信公众后台去申请,前端容易被反编译官方解释https://kf.qq.com/faq/1706236NjINj1706236VRZBR.html,故此,要将你的appid和秘钥保存到后端然后去访问,之前我就犯错误,将访问微信api放到了前端,之所以仍能在模拟器运行,是因为勾选了不校验域名合法性)。
修改后代码如下。

<?php

include_once "wxBizDataCrypt.php";
// 设置API接口的URL
 $appid = '你的appid';
 $secret='你的密钥';
 
 $rescode=$_GET['rescode'];
 
 $encryptedData=$_GET['encryptedData'];

$iv =$_GET['iv'] ;
 //步骤一 访问api 获得数据
$url = 'https://api.weixin.qq.com/sns/jscode2session?appid=' . $appid . '&secret=' . $secret . '&js_code=' . $rescode . '&grant_type=authorization_code';

// 设置请求的header
$options = [
    'http' => [
        'header' => "Authorization: Bearer YOUR_API_TOKEN
" .
                    "Content-Type: application/json
",
        'method' => 'GET',
    ],
];

// 发起请求并获取响应
$response = file_get_contents($url, false, stream_context_create($options));

// 输出API接口返回的数据





//echo $response 


//解析json,获得sesionkey
$jsondata = json_decode($response, true);


$sessionkey =$jsondata['session_key'];

//echo $sessionkey

$pc = new WXBizDataCrypt($appid, $sessionkey);
$errCode = $pc->decryptData($encryptedData, $iv, $data );

if ($errCode == 0) {
    print($data . "\n");
} else {
    print($errCode . "\n");
}
?>

至此后端工作全部完成。接下去就是微信小程序前端代码。
  第四块:微信小程序前端代码,打开微信开发者工具新建一个微信,选择一个不使用云服务JS-基础模板。删除page下其它页面,只保留一个index页面,在app.json中删除其它页面配置,只保留index,清除index.wxml的布局文件,清除index.js的自定义代码及data中定义参数。
  我们先写index.js,在调用wx.getWeRunData,要先用wx.login登录,会获得一个res.code,对对应于访问微信api中的js_code参数,而调用wx.getWeRunData会获得encryptedData和iv,然后wx.request去访问自己的php后端就行了,注意由于是测试,不要点忘记点击微信开发者工具右上角的详情按钮,然后在本地设置中勾上不校验合法域名。

// pages/index/index.js

var common = require('../../utils/common.js')
var util=require('../../utils/util.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 (res2) {
             console.log("wx.getWeRunData成功")
           
               encryptedData = res2.encryptedData; 
               iv = res2.iv;
               that.conndemo(rescode,encryptedData,iv)
              
            },
           fail: function (e) { console.log("wx.getWeRunData获取数据失败") }
       })
              
                 }
            } 
            }) 
  },

  getFullUrl(options) //获得拼接后url,无实际意义,只用于检查url输出是否正确
  {
    // 获取请求的 URL
    let url = options.url;
   
    // 如果 URL 以 ? 结尾,则直接添加 data,否则检查是否已有查询参数,若无则添加 ?
    if (url.endsWith('?')) {
      url += options.data;
    } else {
      let hasQuery = url.includes('?');
      let sep = hasQuery ? '&' : '?';
      url += sep + Object.keys(options.data)
        .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(options.data[key])}`)
        .join('&');
    }
   
    return url;
  },

  conndemo(rescode,encryptedData,iv)
  {
    
    var that=this;
    var url='http://localhost/PHP/demo.php'
    var sessionkey="";
 
   //-----
 
   ///-----
    wx.request({
      url: url,
     
      data:
      {
        
        rescode:rescode,
        grant_type:"authorization_code",
        encryptedData:encryptedData,
        iv:iv,
        
      },
    
      success:function (res) {
      sessionkey=res.data.session_key
      console.log("输出session_key啦"+sessionkey)
      that.setData({
        steplist:res.data.stepInfoList
      })
     // that.conndemo(sessionkey,encryptedData,iv)
     
    }
    })

    let fullUrl = that.getFullUrl({
      url: 'http://localhost/PHP/transferweixinapi.php',
      data: {
        rescode:rescode,
        grant_type:"authorization_code",
        encryptedData:encryptedData,
        iv:iv
        
      }
    });
     
    console.log('Full URL:', fullUrl);
   
  },

  

 

  ts_to_time(timestamp) {
    //const timestamp = 1619183582000;
   // 网上js1970-1-1加多少毫秒,此处是秒,所以*1000
    const date = new Date(timestamp*1000);
    const year = date.getFullYear();
    const month = ('0' + (date.getMonth() + 1)).slice(-2);
    const day = ('0' + date.getDate()).slice(-2);
    const hours = ('0' + date.getHours()).slice(-2);
    const minutes = ('0' + date.getMinutes()).slice(-2);
    const seconds = ('0' + date.getSeconds()).slice(-2);
    //const formattedDate = year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;
    const formattedDate = year + '-' + month + '-' + day ;
    
    return formattedDate

},

 getSecondsDifference(date1, date2) {
  return Math.abs(new Date(date1) - new Date(date2)) / 1000;
}

 



 
  
})

写完index.js写index.wxml,代码如下,其中步数列表有个timestamp,时间戳,需要转年月日,转换的js代码要写wxml上,在wxs标志内写,然后调用。
  代码如下

<wxs module="m1">
var msg = "hello world";

module.exports.message = msg;
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>

至此,全部代码已完成,在模拟器上运行代码,如图14,成功!
  在这里插入图片描述

源码下载地址:https://download.csdn.net/download/wstcl/89124859,查看本人的评论,有彩蛋。

  • 15
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值