微信小程序之获取并解密用户数据(获取openid,nickName等)


声明:本文转载自https://my.oschina.net/xshuai/blog/1800393,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

本文主要总结微信小程序通过后台请求访问微信用户信息

创建一个微信小程序工程(自行百度)

微信小程序index.js代码

//index.js //获取应用实例 const app = getApp() Page({   data: {     motto: 'Hello World',     userInfo: {},     backUserInfo:{},//后台得到的微信用户信息     hasUserInfo: false,     canIUse: wx.canIUse('button.open-type.getUserInfo')   },   //事件处理函数   bindViewTap: function() {     wx.navigateTo({       url: '../logs/logs'     })   },   onLoad: function () {    //1.静默操作获取用户信息 调用wx.login     var that = this;     wx.login({       success:function(res){         var code = res.code;//2.登录凭证code         console.log('code==='+code);         if(null!=code){             wx.getUserInfo({               success:function(ress){                 console.log('res===' + res);                 //3.请求自己的服务器,解密用户信息                  wx.request({                   url: 'http://xxxx.com/wcsp/oauth',                   method:'post',                   header:{                     'content-type': 'application/x-www-form-urlencoded'                   },                   data: { encryptedData: ress.encryptedData, iv: ress.iv, code: code},                   success:function(res){                     console.log('resjava===' + res.data.openId);                     that.setData({                       backUserInfo:res//将后台返回的数据赋值给backUserInfo                     })                   }                 })               }             })         }       }     })     if (app.globalData.userInfo) {       this.setData({         userInfo: app.globalData.userInfo,         hasUserInfo: true       })     } else if (this.data.canIUse){       // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回       // 所以此处加入 callback 以防止这种情况       app.userInfoReadyCallback = res => {         this.setData({           userInfo: res.userInfo,           hasUserInfo: true         })       }     } else {       // 在没有 open-type=getUserInfo 版本的兼容处理       wx.getUserInfo({         success: res => {           app.globalData.userInfo = res.userInfo           this.setData({             userInfo: res.userInfo,             hasUserInfo: true           })         }       })     }   },   getUserInfo: function(e) {     console.log(e)     app.globalData.userInfo = e.detail.userInfo     this.setData({       userInfo: e.detail.userInfo,       hasUserInfo: true     })   } }) 

Java后台处理代码:

import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;  import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;  import cn.xsshome.mvcdo.util.AesCbcUtil; import cn.xsshome.mvcdo.util.PrintUtil; import cn.xsshome.mvcdo.util.WeChatConstant;  import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; /**  * 微信小程序code换取微信用户信息  * @author 小帅丶  *  */ @Controller @RequestMapping(value="wcsp") public class WeChatSPController { 	private static Logger logger = LoggerFactory.getLogger(WeChatSPController.class); 	/** 	 * 获取微信小程序用户openid等信息 	 * @param encryptedData 加密数据 	 * @param iv 加密算法初始向量 	 * @param code 微信小程序code码 	 * @param request HttpServletRequest 	 * @param response HttpServletResponse 	 * @return String 	 * @throws Exception 	 */ 	@RequestMapping(value="/oauth") 	public String wxOauth(String encryptedData,String iv,String code,HttpServletRequest request,HttpServletResponse response) throws Exception{ 		try { 			logger.info("请求的参数有:\n加密数据="+encryptedData+"\n加密算法初始向量="+iv+"\n微信小程序code="+code); 			//1.拼接code等参数换取私钥值 			String param = "appid="+WeChatConstant.WCSP_APPID+"&secret="+WeChatConstant.WCSP_APPSECRET+"&grant_type="+WeChatConstant.GRANT_TYPE+"&js_code="+code; 			String result = cn.xsshome.mvcdo.util.HttpUtil.post(WeChatConstant.JSCODE2SESSION_URL, param); 			logger.info("=======接口返回的数据:"+result); 			JSONObject jsonObject = JSON.parseObject(result); 			String session_key = jsonObject.get("session_key").toString(); 			logger.info("session_key私钥值===="+session_key); 			//2.使用私钥值 和 算法向量值 加密的数据进行解密 			String userInfo = AesCbcUtil.decrypt(encryptedData, session_key, iv, "UTF-8"); 			logger.info("解密后返回页面的数据==="+userInfo); 			PrintUtil.printJson(response, userInfo); 		} catch (Exception e) { 			logger.error("oauth===出错了"+e.getMessage()); 			return null; 		} 		return null; 	} } 

 

AES解密工具类(需要BC包支持文末给出)

package cn.xsshome.mvcdo.util; import org.apache.commons.codec.binary.Base64; import org.bouncycastle.jce.provider.BouncyCastleProvider;  import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.io.UnsupportedEncodingException; import java.security.*; import java.security.spec.InvalidParameterSpecException;  /**  * AES-128-CBC 加密方式  * 注:  * AES-128-CBC可以自己定义“密钥”和“偏移量“。  * AES-128是jdk自动生成的“密钥”。  */ public class AesCbcUtil {     static {         //BouncyCastle是一个开源的加解密解决方案,主页在http://www.bouncycastle.org/         Security.addProvider(new BouncyCastleProvider());     }     /**      * AES解密      * @param data           //密文,被加密的数据      * @param key            //秘钥      * @param iv             //偏移量      * @param encodingFormat //解密后的结果需要进行的编码      * @return      * @throws Exception      */     public static String decrypt(String data, String key, String iv, String encodingFormat) throws Exception {         //被加密的数据         byte[] dataByte = Base64.decodeBase64(data);         //加密秘钥         byte[] keyByte = Base64.decodeBase64(key);         //偏移量         byte[] ivByte = Base64.decodeBase64(iv);         try {             Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");             SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");             AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");             parameters.init(new IvParameterSpec(ivByte));             cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化             byte[] resultByte = cipher.doFinal(dataByte);             if (null != resultByte && resultByte.length > 0) {                 String result = new String(resultByte, encodingFormat);                 return result;             }             return null;         } catch (NoSuchAlgorithmException e) {             e.printStackTrace();         } catch (NoSuchPaddingException e) {             e.printStackTrace();         } catch (InvalidParameterSpecException e) {             e.printStackTrace();         } catch (InvalidKeyException e) {             e.printStackTrace();         } catch (InvalidAlgorithmParameterException e) {             e.printStackTrace();         } catch (IllegalBlockSizeException e) {             e.printStackTrace();         } catch (BadPaddingException e) {             e.printStackTrace();         } catch (UnsupportedEncodingException e) {             e.printStackTrace();         }          return null;     }  }

微信小程序index.wxml内容

<!--index.wxml--> <view class="container">   <view class="userinfo">     <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button>     <block wx:else>       <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" background-size="cover"></image>     </block>   </view>   <view class="infos">     用户昵称:<text class="userinfo-nickname">{{backUserInfo.data.nickName}}</text>   </view>   <view class="infos">     用户性别:<text class="userinfo-nickname" wx:if="{{backUserInfo.data.gender}}==1">男</text>     <text class="userinfo-nickname" wx:elif="{{backUserInfo.data.gender}}==0">女</text>     <text class="userinfo-nickname" wx:else>未知</text>   </view>   <view class="infos">     所在城市:<text class="userinfo-nickname">{{backUserInfo.data.city}}</text>   </view>     <view class="infos">     所在省份:<text class="userinfo-nickname">{{backUserInfo.data.province}}</text>   </view>     <view class="infos">     所在国家:<text class="userinfo-nickname">{{backUserInfo.data.country}}</text>   </view>     <view class="infos">     用户的语言:<text class="userinfo-nickname">{{backUserInfo.data.language}}</text>   </view> </view>

所需要的jar包

  		<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15 --> 		<dependency> 		    <groupId>org.bouncycastle</groupId> 		    <artifactId>bcprov-jdk15</artifactId> 		    <version>1.46</version> 		</dependency>

演示效果图

后台打印的日志

加密数据=X5Ib86RrR0DbekjW1qnfSDYjcQ2fZ2e9jEzcqiHS54nW/jDPa/qUEAJAXPjB7kDAvjSVoOQ9BGPn2BGruoGyMXssDQHWAsdw9u/dlTPVLuwrKmtiBArgEpeWmYy70+DU3vCrYTFHgXLsg5KWgvXpuhgkz7lcafCr9CBTeq3uIEZ40nNfXJiMeFiQrjT/vCvK8bLWrGv5qBF1LlxlA/7Cxx8oQuAHKjXPaIMjEq+r0/wOhBV13J6n1BZF1J7A0HrtXsy1uw56wAbcJXvWx0dvrS0+Kk//P9uYzOK3+DFHxsne2P2cd1KBqWVY+gg0VWZ8wvYt/FNq9l6zM1RehHCS0Zt3nAjQebHb5IaFSMHjA4qrL21jpjoAAX6SbfgXoLDnENG2cmppqPWBCLAJ6rizTSkAc67sOm9674s4KMz7z8LJr/RIsEnGOMeMhb7ylt3vH+fMtwAA7N9B0wjD908MgtGTPvUhoags/LoqXfpm8DI= 加密算法初始向量=P5ZaAJxSuDBzV6IyxKyPhw== 微信小程序code=081hg8Ez1HvYBe0vDnEz1dwdEz1hg8Ed result:{"session_key":"JzWvgMpc9CoWVd7fUVhE0A==","expires_in":7200,"openid":"op5Hs0EYFmR7XvvWNrbsMFVn22Kk"} [cn.xsshome.mvcdo.controller.wechat.WeChatSPController] - =======接口返回的数据:{"session_key":"JzWvgMpc9CoWVd7fUVhE0A==","expires_in":7200,"openid":"op5Hs0EYFmR7XvvWNrbsMFVn22Kk"} [cn.xsshome.mvcdo.controller.wechat.WeChatSPController] - session_key私钥值====JzWvgMpc9CoWVd7fUVhE0A== [cn.xsshome.mvcdo.controller.wechat.WeChatSPController] - 解密后返回页面的数据==={"openId":"op5Hs0EYFmR7XvvWNrbsMFVn22Kk","nickName":"小帅丶","gender":1,"language":"zh_CN","city":"Haidian","province":"Beijing","country":"China","avatarUrl":"https://wx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTLib098UOLAHuE1fDldajSPuwR0RcPf3rxCtVicwhvdKibYFE0JNibwMwGdiagRzibdAtkSTU1fYxiaz8CIQ/0","watermark":{"timestamp":1524554676,"appid":"wxe71f579c17281234"}} 

本文发表于2018年04月24日 22:38
(c)注:本文转载自https://my.oschina.net/xshuai/blog/1800393,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2175 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1