您现在的位置: 微信小程序 > 微信小程序开发 > 教程 >

nyoj_lvy实战开发系列《一》:发送JSON信息,加密数据解密算法,UnionID机制说明

来源:微信小程序 编辑:Yiyongtong.com 发布时间:2018-02-10 12:09热度:

前期小程序开发只进行到根据微信用户登录获取的code 去微信的API去获取到该用户的openId和session_key,到了第二阶段,老大让我重写OAuthManager的代码来实现微信小程序和微信公众号平台获取用户信息的优化,即将OAuthManager重写成父类抽象类,微信小程序(WechatAppManager)和微信公众号(PublicAccountMananger)来继承并开发,具体方法不赘述。。。

在开发微信小程序的时候,由于对于需求的不理解,导致半天都发在获取用户信息的方法上,由于微信小程序没有access_token,所以,用户信息只能从前台发出,后台负责接收并封装JSON格式的用户信息。。。

在这里,我要重点阐述我在发送JSON信息时候所遇到的低级错误!!!

1.发送JSON格式信息,需要Headers添加


				
  1. Content-Type:application/json

后台始终接收不到,就因为少了一个这个headers,接着因为JSON的格式是


				
  1. {
    "code": "CODE",
    "wechatAppUserInfo": {
    "errMsg": "getUserInfo:ok",
    "rawData": "{\"nickName\":\"NICKNAME\",\"gender\":0,\"language\":\"LANGUAGE\",\"city\":\"CITY\",\"province\":\"PROVINCE\",\"country\":\"COUNTRY\",\"avatarUrl\":\"AVATARURL\"}",
    "signature": "SIGNATURE",
    "encryptData": "ENCRYPTDATA"
    }
    }

请注意好JSON格式,格式错了也是发不过去的,可以上网在线监测自己的JSON格式,后台接收的时候,我出于方便的目的,用dto的形式接收将json数据封装成一个dto,直接接收


				
  1. public String getSessionByCode(@RequestBody WechatAppUser wechatAppUser, HttpServletRequest request)

WechatAppUser里只有两个属性(code , wechatAppUserInfo(wechatAppUserInfo)是一个封装类)  我将rawData和encryptData也进行了封装。。。

经过一系列的封装,反序列化之后,我们需要将encryptData数据进行解密,这个解密的过程让我心焦。。。  整了两天才发现原来是自己的数据出问题。。。  加密数据解密算法

接口如果涉及敏感数据(如wx.getUserInfo当中的 openid ),接口的明文内容将不包含敏感数据。开发者如需要获取敏感数据,需要对接口返回的加密数据( encryptData )进行对称解密。 解密算法如下:

1.对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充。
2.对称解密的目标密文为 Base64_Decode(encryptData),
3.对称解密秘钥 aeskey = Base64_Decode(session_key), aeskey 是16字节
4.对称解密算法初始向量 iv = aeskey, 同样是16字节 

上网各种百度该解密算法,让我在千万条链接中找到了它 
http://blog.csdn.net/aflight/article/details/13626385 
这个链接的key和iv是自动生成的,需要自己手动修改代码(iv的生成需要传入session_key转化的byte[])


				
  1. //生成iv
    public static AlgorithmParameters generateIV(byte [] iv) throws Exception{
    //iv 为一个 16 字节的数组,这里采用和 iOS 端一样的构造方法,数据全为0
    AlgorithmParameters params = AlgorithmParameters.getInstance(KEY_ALGORITHM);
    params.init(new IvParameterSpec(iv));
    return params;
    }
    
    //转化成JAVA的密钥格式
    public static Key convertToKey(byte[] keyBytes) throws Exception{
    SecretKey secretKey = new SecretKeySpec(keyBytes,KEY_ALGORITHM);
    return secretKey;
    }

解密的代码


				
  1. byte[] data = WechatAppDecryptor.decrypt(wechatAppUser.getWechatAppUserInfo().getEncryptData(),
    oAuthResult.getSession_key());
    logger.debug("解密得到的数据 : " + new String(data,"UTF-8"));
    wechatAppUser.getWechatAppUserInfo().setEncryptDatas(CacheUtil.doJacksonDeserialize(new String(data,"UTF-8"),EncryptData.class));

灰常好,这里我们就可以得到微信用户的基本信息以及最重要的unionId  UnionID机制说明:

如果开发者拥有多个移动应用、网站应用、和公众帐号(包括小程序),可通过unionid来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号(包括小程序),用户的unionid是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionid是相同的。

简而言之就是根据这个字段,用户在数据库中只会存在一条数据!!!

encryptData 解密后为以下 json 结构


				
  1. {
    "openId": "OPENID",
    "nickName": "NICKNAME",
    "gender": 1,
    "city": "CITY",
    "province": "PROVINCE",
    "country": "COUNTRY",
    "avatarUrl": "AVATARURL",
    "unionId": "UNIONID"
    }