最近写小程序的时候遇到一个问题,获取对于java小白而言,获取微信运动步数还是有点困难,下面为大家介绍一下我是怎么获取微信运动步数的。
原理:
详情请去这个网址:
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html
解决:
首先微信小程序端需要通过wx.login来获取用户的session_key,该文件名为:app.js
App({
onLaunch: function() {
wx.login({
success: result => {
wx.request({
url: 'http://localhost:8080/wx/login',
data: {
code: result.code
},
success: res => {
//获取响应结果里的session_key
this.globalData.sessionKey = res.result.session_key;
},
fail: err => {
console.log(err);
}
})
}
})
},
globalData: {
userInfo: null,
sessionKey: null
}
})
服务器端通过接受传过来的code,然后通过另外一个接口来获取用户的session_key和open_id,目前只会用到session_key.
@GetMapping("/wx/login")
public Result<?> wxLogin(String code) {
String openId = "";
JSONObject openIdObject = null;
try {
openId = new HttpRequestor().doGet(WxUtils.url + code + WxUtils.url0);
//alibaba的json
openIdObject = JSON.parseObject(openId);
} catch (Exception e) {
e.printStackTrace();
}
return Result.ok(openIdObject);
}
WxUtil文件,工具类借鉴:
https://blog.csdn.net/macex002/article/details/81200185?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
public class WxUtils {
private static final String APP_ID = "小程序APPID";
private static final String SECRET = "小程序SECRET";
String openId = "";
public static String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + APP_ID + "&secret=" + SECRET + "&js_code=";
public static String url0 = "&grant_type=authorization_code";
// 步数转卡路里
public static float getDistanceByStep(long steps) {
return steps * 0.6f / 1000;
}
/**
* 微信解密运动步数
*
* @param sessionKey
* @param encryptedData
* @param iv
* @return
*/
public static String decryptWeChatRunInfo(String sessionKey, String encryptedData, String iv) {
String result = null;
byte[] encrypData = Base64.decodeBase64(encryptedData);
byte[] ivData = Base64.decodeBase64(iv);
byte[] sessionKeyB = Base64.decodeBase64(sessionKey);
try {
AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivData);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(sessionKeyB, "AES");
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
byte[] doFinal = cipher.doFinal(encrypData);
result = new String(doFinal);
}catch (Exception e){
e.printStackTrace();
}
return result;
}
}
引用maven
<!-- json -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.60</version>
</dependency>
微信端获取运动步数,通过后端的接口将encryptedData,iv,sessionKey发送给后端.后端来解密.
getRunData() {
wx.getWeRunData({
success: function (res) {
wx.request({
url: 'http://localhost:8080/wx/runData',
method: 'post',
header: {
'content-type': 'application/json'
},
data: {
iv: res.iv,
encryptedData: res.encryptedData,
sessionKey: app.globalData.sessionKey
},
success: res => {
console.log(res);
},
fail: err => {
wx.showModal({
title: '提示',
content: '请先关注“微信运动”公众号并设置数据来源,以获取并提供微信步数数据',
showCancel: false,
confirmText: '知道了'
})
}
})
}
})
}
后端接受到数据,通过AES解密
@PostMapping("/runData")
public Result<?> runData(@RequestBody WxEntity wxEntity) {
String encryptedData = wxEntity.getEncryptedData();
String iv = wxEntity.getIv();
String sessionKey = wxEntity.getSessionKey();
if (encryptedData == null && iv == null && sessionKey == null) {
return Result.error("错误,没有数据");
}
String decrypt = null;
//解密
try {
decrypt = WxUtils.decryptWeChatRunInfo(sessionKey, encryptedData, iv);
} catch (Exception e) {
e.printStackTrace();
}
if (decrypt == null) {
log.info("解密失败");
} else {
log.info("解析成功");
}
JSONObject stepInfoListJson = JSON.parseObject(decrypt);
//解析json,获取stepInfoList下面的步数
JSONArray stepInfoList = JSON.parseArray(stepInfoListJson.getString("stepInfoList"));
//获取今天的步数
JSONObject today = Objects.requireNonNull(stepInfoList).getJSONObject(0);
return Result.ok(today);
}