Java開發微信小程式(二)獲取並解密小程式使用者和手機資訊
第二篇 獲取並解密小程式的加密資訊包括使用者和手機資訊。
如果對其他的資訊幹興趣,還可以點選以下的連線
2.獲取並解密小程式的加密資訊包括使用者和手機資訊。
3.用小程式給使用者推送服務訊息。
4.給繫結小程式而且又關注微信公眾號的使用者推送公眾號訊息。
好的,開始我們的獲取和解密操作吧,主要有以下這些步驟
1.小程式客戶端呼叫wx.login(),獲取到票據code。(請參照第一篇)
2.然後將code傳送到Java伺服器,接下來在java後臺我們用儲存好的AppID,AppSecret和傳遞過來的code,呼叫
3.伺服器拿到session_key後,會將它儲存在伺服器的快取中;因為微信團隊不建議直接將session_key在網路上傳輸,由開發者自行生成唯一鍵與session_key關聯。其作用是維護小程式登入態,如果使用者重新登入或超時需要重新獲取session_key。(請參照第一篇)
4.1通過wx.getUserInfo可以獲取到使用者敏感資料encryptedData 。
呼叫前需要 使用者授權,彈出授權視窗,請使用 <button open-type="getUserInfo"/>
// 獲取使用者資訊 wx.getSetting({ success: res => { if (res.authSetting['scope.userInfo']) { // 已經授權,可以直接呼叫 getUserInfo 獲取頭像暱稱,不會彈框 wx.getUserInfo({ success: res => { console.log(res.userInfo.avatarUr); console.log(res.userInfo); } }) } } })
4.2通過getPhoneNumber可以獲取到使用者敏感資料encryptedData 。
獲取微信使用者繫結的手機號,需先呼叫wx.login介面。
<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber"></button>
getPhoneNumber(e) {
console.log(e)
console.log(e.detail.errMsg)
console.log(e.detail.iv)
console.log(e.detail.encryptedData)
}
5.客戶端將加密資料encryptedData、session_key和偏移量iv一起傳送到Java伺服器
//將獲取到的iv和encryptedData傳送到java後臺解密
wx.request({
url: "https://www.test.com/app/interface/miniprogram/miniprogramDecrypt",
data: {
head: {},
body: {
encryptedData: e.detail.encryptedData,
iv: e.detail.iv,
openId: "E67148F6DB22D1E53E3B760B2B556FD5C2701F0AC0CF8987D71D6E4711FCBF737E099DA6057C35DC13D0D886066610E6"
}
},
method: "POST",
header: {
'content-type': 'application/json',
},
success: function (res) {
console.log(res);
},
fail: function (error) {
console.log(error);
}
})
6.Java伺服器接受到傳遞過來的引數encryptedData和偏移量iv,在從快取中獲取session_key
public class MiniprogramDecryptDataInterfaceAction extends BaseInterfaceAction {
private static final Logger logger = LoggerFactory.getLogger(MiniprogramDecryptDataInterfaceAction.class);
@Override
public String execute() throws Exception {
logger.debug("小程式加密資料解密-----開始");
// 獲取前端傳遞的資料
HttpServletRequest request = this.getRequest();
String appId = "你的開發者Id";
String encryptedData = request.getParameter("encryptedData");
//使用者唯一標識,通過openId獲取預先從微信端取到的session_key
String openId = request.getParameter("openId");
String iv = request.getParameter("iv");
//呼叫通用方法解密
String decryptData = MiniprogramUtil.getDecryptedData(appId, openId, encryptedData, iv);
logger.debug("小程式加密資料解密結束返回資料:" + decryptData);
return null;
}
}
/**
* 對加密資料進行解密並返回結果
*
* @param mByte
* @return
* @throws Exception
*/
public static String getDecryptedData(String appId, String openId, String encryptedData, String iv)
throws Exception {
String result = "";
//根據openId從session中取得sessionKey
String sessionKey = getSessionKey(openId);
if (StringUtils.isNotBlank(appId)) {
//根據appId和sessionKey對加密資料進行解密
WXBizDataCrypt pc = new WXBizDataCrypt(appId, sessionKey);
result = pc.decryptData(encryptedData, iv);
}
return result;
}
7.Java伺服器使用AES解密方法對encryptedData進行解密,從而實現使用者敏感資料解密
解密需要參考的文章:
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html
/**
* 對微信小程式使用者加密資料的解密
*
* @author 網行天下
*/
public class WXBizDataCrypt {
private String appid;
private String sessionKey;
public WXBizDataCrypt(String appid, String sessionKey) {
this.appid = appid;
this.sessionKey = sessionKey;
}
/**
* 檢驗資料的真實性,並且獲取解密後的明文.
*
* @param encryptedData
* string 加密的使用者資料
* @param iv
* string 與使用者資料一同返回的初始向量
*
* @return data string 解密後的原文
* @throws InvalidAlgorithmParameterException
* @throws UnsupportedEncodingException
*/
public String decryptData(String encryptedData, String iv) throws Exception {
String userInfo = "";
if (StringUtils.length(sessionKey) != 24) {
return "ErrorCode::$IllegalAesKey;";
}
// 對稱解密祕鑰 aeskey = Base64_Decode(session_key), aeskey 是16位元組。
byte[] aesKey = Base64.decodeBase64(sessionKey);
if (StringUtils.length(iv) != 24) {
return "ErrorCode::$IllegalIv;";
}
// 對稱解密演算法初始向量 為Base64_Decode(iv),其中iv由資料介面返回。
byte[] aesIV = Base64.decodeBase64(iv);
// 對稱解密的目標密文為 Base64_Decode(encryptedData)
byte[] aesCipher = Base64.decodeBase64(encryptedData);
byte[] resultByte = AESUtils.decrypt(aesCipher, aesKey, aesIV);
if (null != resultByte && resultByte.length > 0) {
userInfo = new String(resultByte, "UTF-8");
}
return userInfo;
}
}
用到maven依賴
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.9</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.32</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.55</version>
</dependency>
8.本文遇到的一些問題和參考文獻
https://blog.csdn.net/will_awoke/article/details/79155182