创建第三方服务器工程
我们知道小程序是基于微信团队开发的IDE,设计模式类似Vue.js。
新建项目时首先需要选择->建立第三方服务器。(小程序版本更新快,已经集成多种开发模式。在此,为何不选择最方便的开发模式,因为最开始开发此项目时还未出现各种云服务开发等。)
用户微信身份授权
image
可以查看微信官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/
详细了解如何获取openid和session_key。
微信运动-前端处理
发送请求:
var code
// 登录
wx.login({
success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
code = res.code
}
})
wx.getWeRunData({
success(res) {
var encryptedData = res.encryptedData
var iv = res.iv
wx.request({
url: app.globalData.host + "/Cal/step",
method: "post",
header: {
'content-type': 'application/json',
'cookie': cookie
},
data: {
code: code,
encryptedData: encryptedData,
iv: iv
},
success: function(res) {
res = res.data
console.log(res)
if (res.status == "1") {
self.setData({
step: res.step
})
}
setTimeout(() => {
wx.hideLoading()
wx.stopPullDownRefresh();
}, 1000)
}
})
}
})
其中encryptedData,iv是做为获取运动步数的依据
image.png
前端将 code,encryptedData,iv的加密数据提交到后台处理。
微信运动-后端处理
controller层获取数据:
@PostMapping("/step") // 用户授权获取微信步数
public Map<String, Object> step(@RequestBody pass pass1) throws Exception {
Map<String, String> param = new HashMap<String, String>();
Map<String, Object> msg1 = new HashMap<String, Object>();
// 登录凭证不能为空
if (pass1.getCode() == null || pass1.getCode().length() == 0) {
msg1.put("status", "0");
msg1.put("msg", "code 不能为空");
return msg1;
}
//获取用户的code,用过URL和APPID 和 SECREET还有code向微信服务器获得OPENID和SEESION_KEY
String url = "https://api.weixin.qq.com/sns/jscode2session";
param.put("appid", "你的微信appid");
param.put("secret", "获取到的secret加密串");
param.put("js_code", pass1.getCode());
param.put("grant_type", "authorization_code");
String wxResult = HttpClientUtil.doGet(url, param);
WXSessionModel wxSessionModel = JsonUtils.jsonToPojo(wxResult, WXSessionModel.class);
String sessionkey = wxSessionModel.getSession_key();
String openid = wxSessionModel.getOpenid();
System.out.println("用户步数session_key:" + sessionkey);
try {
// 利用AES类Base64解密算法解密用户敏感信息
byte[] bytes = AES.decrypt(Base64.decodeBase64(sessionkey),
Base64.decodeBase64(pass1.getIv()),
Base64.decodeBase64(pass1.getEncryptedData()));
String theStep = new String(bytes, "UTF8");
System.out.println(theStep);// 解密后获取到用户过去30天的JSON字符串组成的步数
JSONObject jsonObject = JSON.parseObject(theStep);// 将字符串转化为json形式取出今日步数
JSONObject jsstep = (JSONObject) jsonObject.getJSONArray("stepInfoList").get(30);// 获取微信用户当前步数
String getstep = jsstep.getString("step");
int step= Integer.parseInt(getstep);
msg1.put("status", "1");
msg1.put("step",step);
} catch (Exception e) {
e.printStackTrace();
}
return msg1;
}
创建AES类Base64解密算法
public class AES {
/**
* 解密算法
* @param sessionkey 小程序登录sessionKey
* @param iv 向量
* @param encryptedData
* @return
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
* @throws InvalidAlgorithmParameterException
* @throws InvalidKeyException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
*/
public static byte[] decrypt(byte[] sessionkey, byte[] iv, byte[] encryptedData)
throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException,
InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(sessionkey, "AES");
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
return cipher.doFinal(encryptedData);
}
}
HttpClientUtil.java 发送请求至微信服务器
public class HttpClientUtil {
public static String doGet(String url, Map<String, String> param) {
// 创建Httpclient对象
CloseableHttpClient httpclient = HttpClients.createDefault();
String resultString = "";
CloseableHttpResponse response = null;
try {
// 创建uri
URIBuilder builder = new URIBuilder(url);
if (param != null) {
for (String key : param.keySet()) {
builder.addParameter(key, param.get(key));
}
}
URI uri = builder.build();
// 创建http GET请求
HttpGet httpGet = new HttpGet(uri);
// 执行请求
response = httpclient.execute(httpGet);
// 判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == 200) {
resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (response != null) {
response.close();
}
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
public static String doGet(String url) {
return doGet(url, null);
}
public static String doPost(String url, Map<String, String> param) {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
// 创建参数列表
if (param != null) {
List<NameValuePair> paramList = new ArrayList<NameValuePair>();
for (String key : param.keySet()) {
paramList.add(new BasicNameValuePair(key, param.get(key)));
}
// 模拟表单
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
httpPost.setEntity(entity);
}
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
public static String doPost(String url) {
return doPost(url, null);
}
public static String doPostJson(String url, String json) {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
// 创建请求内容
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
httpPost.setEntity(entity);
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
}
JsonUtils.java 用于将对象转化为json字符串
public class JsonUtils {
// 定义jackson对象
private static final ObjectMapper MAPPER = new ObjectMapper();
/**
* 将对象转换成json字符串。
* <p>Title: pojoToJson</p>
* <p>Description: </p>
* @param data
* @return
*/
public static String objectToJson(Object data) {
try {
String string = MAPPER.writeValueAsString(data);
return string;
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
/**
* 将json结果集转化为对象
*
* @param jsonData json数据
* @param clazz 对象中的object类型
* @return
*/
public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
try {
T t = MAPPER.readValue(jsonData, beanType);
return t;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 将json数据转换成pojo对象list
* <p>Title: jsonToList</p>
* <p>Description: </p>
* @param jsonData
* @param beanType
* @return
*/
public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) {
JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
try {
List<T> list = MAPPER.readValue(jsonData, javaType);
return list;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
以上是做为第三方服务器需要获取到微信运动的流程。