前段时间因工作需要,研究了一下微信小程序Java服务端开发,今天简单整理一下相关步骤。
1、获取code、encryptedData、iv:
code需要前端通过调用微信api --> wx.login(OBJECT)获取。
encryptedData和iv需要前端通过调用微信api --> wx.getUserInfo(OBJECT)获取。
其中encryptedData是包含用户信息的加密数据,需要服务端解密。
2、服务端获取sessionkey和openid:
首先,服务端拿到code以后,先通过调用微信api接口:
https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
来换取sessionkey。
其中的appid、secret都是申请小程序时微信已经分配好的常量。js_code是上面步骤中从前端获取。
调用接口后,会返回sessionkey和openid。
3、解密用户信息:
根据官方文档,解密数据算法如下:
对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充。 对称解密的目标密文为 Base64_Decode(encryptedData)。 对称解密秘钥 aeskey = Base64_Decode(session_key), aeskey 是16字节。 对称解密算法初始向量 为Base64_Decode(iv),其中iv由数据接口返回。
网上查找了一些资料,由于jdk本身不支持aes-128-cbc pksc#7算法,所以如果使用java语言进行解密,需要下载算法工具包。官网地址如下 http://www.bouncycastle.org/latest_releases.html 。
最后,根据上面的解密算法步骤,Java版实现代码如下:
byte[] encryptedDataBytes = new BASE64Decoder().decodeBuffer(encryptedData);
byte[] keyBytes = new BASE64Decoder().decodeBuffer(sessionKey);
byte[] ivBytes = new BASE64Decoder().decodeBuffer(iv);
AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
params.init(new IvParameterSpec(ivBytes));
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Key secretKey = new SecretKeySpec(keyBytes,"AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
cipher.init(Cipher.DECRYPT_MODE,secretKey,params);
byte[] data = cipher.doFinal(encryptedDataBytes);
String decryptedData = new String(data,"UTF-8");
解密后的decryptedData是一个json,
{ "openId": "OPENID", "nickName": "NICKNAME", "gender": GENDER, "city": "CITY", "province": "PROVINCE", "country": "COUNTRY", "avatarUrl": "AVATARURL", "unionId": "UNIONID", "watermark": { "appid":"APPID", "timestamp":TIMESTAMP } }
其中的unionId,可以唯一标识当前用户。
可再使用该unionId换取自己系统的userId做到登陆打通。
备注:
以上整理了一个微信小程序服务端的简单流程,但根据官方api文档,还有一些如签名校验、水印校验、checkSession等步骤,官方文档写的很清楚,这里就不写了,直接看文档吧(小程序官方文档开放接口部分):https://mp.weixin.qq.com/debug/wxadoc/dev/api/api-login.html