问题:wx.getUserInfo 解密用户信息出现概率性失败
正确顺序: wx.login() =>wx.getUserInfo
1.首先我们来讨论下:wx.login()后执行了什么 *** 坦搏作?
刷新登录状态让携祥,概率性生成新的 sessionKey(密钥) 和与其对应的 encryptedData(加密数据)
2.再有一点: sessionKey 是有时效性的,如果通过缓存拿取的话,需要先 wx.checkSession()进行检测是否过期
3.那我们就能发现:在先授权(先拿到encryptedData),再调用wx.login()的情况下:
(1).一旦生成了新的sessionKey,就会导致旧的encryptedData无法被解密
(2).即使sessionKey未刷新但是sessionKey过期也会导致无法解密
所以最终解决方案:进入授权页面即调隐让用wx.login(),刷新登录状态(能避免 sessionKey 过期),再进行授权。
通过wx.getUserInfo获取用户的openId 和unionId,需要对接口返回的加密数据( encryptedData )进行对称解密。
/**
* 功能描述: <br>
* 〈功能详细描述〉
*
*@paramargs
*@see[相关类/方法](可逗穗兄选)
*@since[产品/模块版本](可选)
*/
publicstaticvoidmain(String[] args){
String encryptedData ="********......*******"
String sessionKey ="********......*******"
String iv ="9btKSYjvtGMGpknPpjS2Ag=="
JSONObject jsonObject = getUserInfo(encryptedData, sessionKey, iv)
System.out.println(jsonObject.getString("unionId"))
System.out.println(jsonObject.toJSONString())
}
结果运行报错:
javax.crypto.BadPaddingException: pad block corrupted
at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$BufferedGenericBlockCipher.doFinal(Unknown Source)
at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(Unknown Source)
at javax.crypto.Cipher.doFinal(Cipher.java:2087)
at com.saic.ebiz.service.util.AESUtils.getUserInfo(AESUtils.java:62)
at com.saic.ebiz.service.util.AESUtils.main(AESUtils.java:86)
Exception in thread"main"java.lang.NullPointerException
at com.saic.ebiz.service.util.AESUtils.main(AESUtils.java:87)
查询原因,有可能是我族拦的wx.login在wx.getUserInfo之后调的原因,细究一下
我们通过wx.login获得用户授权码code,接下来我们用code以及appid和appSecret请求微信
https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
获取session_key,而sessionKey又是解密encryptedData的密钥,所以一旦我们的wx.login在wx.getUserInfo之后获取,我们redis中存储的sessionKey绝对不是当前获取encryptedData的密钥。所以更改小程序请求顺序,每次请求wx.getUserInfo之前先请求wx.login,同时生成sessionKey放入缓存。而后需要解密的时候就可以正常解密了
特别注意: 让前端看一下你的请求顺序山袭是不是错了
这种情况偶发,一般发生在隔一段时间之后第一次登录时。
导致问题的原因是 getUserInfo 放在了 wx.login 之前。 getUserInfo 获清和取到 iv 和 encryptedData 传给后台。wx.login调用时用户的 session_key 可能会被更新而致使旧 session_key 失效。这样后台再去解密的时候就等于在用新的 session_key 去解密旧的 session_key 加密的数据,就会报 ILLEGAL_BUFFER 错误。
正常的流程应该是:
很容易错写成在 wx.getUserInfo 的回调里再调 wx.login 拿 code 再发送给服务器,局携这样 getUserInfo 里的 data 加密用的session_key就有可能跟解密的时候的 session_key 不一致,因为 wx.login 有可能会刷新了 session_key
建议开发者提前进行 login;或者在回调中先使用 checkSession 进行登录态检查,避免 login 刷新登录答腊盯态。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)