Java开发微信小程序(二)获取并解密小程序用户和手机信息

第二篇 获取并解密小程序的加密信息包括用户和手机信息。

如果对其他的信息干兴趣,还可以点击以下的连接

1.小程序登录获取,小程序的openId和unionId。

2.获取并解密小程序的加密信息包括用户和手机信息。

3.用小程序给用户推送服务消息。​​​​​​​

4.给绑定小程序而且又关注微信公众号的用户推送公众号消息。

好的,开始我们的获取和解密操作吧,主要有以下这些步骤

1.小程序客户端调用wx.login(),获取到票据code。(请参照第一篇

2.然后将code发送到Java服务器,接下来在java后台我们用保存好的AppID,AppSecret和传递过来的code,调用 code2Session 接口获取openId,unionId和session_key(会话密钥)。(请参照第一篇

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

https://blog.csdn.net/dafeige8/article/details/76019911

https://blog.csdn.net/zzm568599448/article/details/50516423

猜你喜欢

转载自blog.csdn.net/ieflex/article/details/83150308
今日推荐