• 简书网微信公众号二维码
您当前的位置: 首页 > 知识百科 > 小程序获取用户微信号怎么操作?

小程序获取用户微信号怎么操作?

时间:2023-07-01 14:05 阅读数:397 人阅读 分类:知识百科

  经常有朋友向小编询问小程序获取用户微信号要怎么操作,其实小程序获取用户微信号属于解密小程序用户数据,而整个解密的过程需要使用到小程序服务器。一起来看看教程吧。

  加密过程微信服务器完成,解密过程在小程序和自身服务器完成,即由 encryptData 得到如下小程序数据:

  {

  "openId": "OPENID",

  "nickName": "NICKNAME",

  "gender": GENDER,

  "city": "CITY",

  "province": "PROVINCE",

  "country": "COUNTRY",

  "avatarUrl": "AVATARURL",

  "unionId": "UNIONID",

  "watermark":

  {

  "appid":"APPID",

  "timestamp":TIMESTAMP

  }

  }

  准备知识:

  Base64编解码

  AES算法、填充模式、偏移向量

  session_key会话密钥,以及怎么存储和获取

  以上3点对于理解解密流程非常重要。

  根据官方文档,我梳理了大致的解密流程,如下:

  小程序客户端调用wx.login,小程序回调里面包含js_code。

  然后将js_code发送到服务器A(开发者服务器),服务器A向微信服务器发起请求附带js_code、appId、secretkey和grant_type参数,以换取用户的openid和session_key(会话密钥)。

  服务器A拿到session_key后,生成一个随机数我们叫3rd_session,以3rdSessionId为key,以session_key + openid为value缓存到redis或memcached中;因为微信团队不建议直接将session_key在网络上传输,由开发者自行生成唯一键与session_key关联。其作用是:

  将3rdSessionId返回给客户端,维护小程序登录态。

  通过3rdSessionId找到用户session_key和openid。

  客户端拿到3rdSessionId后缓存到storage,

  通过wx.getUserIinfo可以获取到用户敏感数据encryptedData 。

  客户端将encryptedData、3rdSessionId和偏移量一起发送到服务器A

  服务器A根据3rdSessionId从缓存中获取session_key

  在服务器A使用AES解密encryptedData,从而实现用户敏感数据解密

  重点在6、7、8三个环节。

  AES解密三个参数:

  密文 encryptedData

  密钥 aesKey

  偏移向量 iv

  服务端解密流程:

  密文和偏移向量由客户端发送给服务端,对这两个参数在服务端进行Base64_decode解编码操作。

  根据3rdSessionId从缓存中获取session_key,对session_key进行Base64_decode可以得到aesKey,aes密钥。

  调用aes解密方法,算法为 AES-128-CBC,数据采用PKCS#7填充。

  下面结合小程序实例说明解密流程:

  微信登录,获取用户信息

  var that = this;

  wx.login({

  success: function (res) {

  //微信js_code

  that.setData({wxcode: res.code});

  //获取用户信息

  wx.getUserInfo({

  success: function (res) {

  //获取用户敏感数据密文和偏移向量

  that.setData({encryptedData: res.encryptedData})

  that.setData({iv: res.iv})

  }

  })

  }

  })

  使用code换取3rdSessionId

  var client = require('../../utils/client.js')

  VAR that = this

  //client.req(url, data, method, success, fail)

  client.req(

  'localhost:8090/wxappservice/api/v1/wx/getSession',

  {

  apiName: 'WX_CODE',

  code: this.data.wxcode

  },

  'GET',

  function(result){

  var thirdSessionId = result.data.data.sessionId;

  that.setData({thirdSessionId: thirdSessionId})

  //将thirdSessionId放入小程序缓存

  wx.setStorageSync('thirdSessionId', thirdSessionId)

  },

  function(result){

  console.log(result)

  }

  );

  发起解密请求

  //client.req(url, data, method, success, fail)

  client.req(

  'localhost:8090/wxappservice/api/v1/wx/decodeUserInfo',

  {

  apiName: 'WX_DECODE_USERINFO',

  encryptedData: this.data.encryptedData,

  iv: this.data.iv,

  sessionId: wx.getStorageSync('thirdSessionId')

  },

  'GET',

  function(result){

  //解密后的数据

  console.log(result.data)

  },

  function(result){

  console.log(result)

  }

  );

  服务端解密实现(java)

  /**

  * 解密用户敏感数据

  * @param encryptedData 明文

  * @param iv 加密算法的初始向量

  * @param sessionId 会话ID

  * @return

  */

  @Api(name = ApiConstant.WX_DECODE_USERINFO)

  @RequestMapping(value = "/api/v1/wx/decodeUserInfo", method = RequestMethod.GET, produces = "application/json")

  public Map decodeUserInfo(@RequestParam(required = true,value = "encryptedData")String encryptedData,

  @RequestParam(required = true,value = "iv")String iv,

  @RequestParam(required = true,value = "sessionId")String sessionId){

  //从缓存中获取session_key

  Object wxSessionObj = redisUtil.get(sessionId);

  if(null == wxSessionObj){

  return rtnParam(40008, null);

  }

  String wxSessionStr = (String)wxSessionObj;

  String sessionKey = wxSessionStr.split("#")[0];

  try {

  AES aes = new AES();

  byte[] resultByte = aes.decrypt(Base64.decodeBase64(encryptedData), Base64.decodeBase64(sessionKey), Base64.decodeBase64(iv));

  if(null != resultByte && resultByte.length > 0){

  String userInfo = new String(resultByte, "UTF-8");

  return rtnParam(0, userInfo);

  }

  } catch (InvalidAlgorithmParameterException e) {

  e.printStackTrace();

  } catch (UnsupportedEncodingException e) {

  e.printStackTrace();

  }

  return rtnParam(50021, null);

  }

  AES解密核心代码

  public byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws InvalidAlgorithmParameterException {

  initialize();

  try {

  Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");

  Key sKeySpec = new SecretKeySpec(keyByte, "AES");

  cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化

  byte[] result = cipher.doFinal(content);

  return result;

  } catch (NoSuchAlgorithmException e) {

  e.printStackTrace();

  } catch (NoSuchPaddingException e) {

  e.printStackTrace();

  } catch (InvalidKeyException e) {

  e.printStackTrace();

  } catch (IllegalBlockSizeException e) {

  e.printStackTrace();

  } catch (BadPaddingException e) {

  e.printStackTrace();

  } catch (NoSuchProviderException e) {

  // TODO Auto-generated catch block

  e.printStackTrace();

  } catch (Exception e) {

  // TODO Auto-generated catch block

  e.printStackTrace();

  }

  最后的效果如下:

  参照上述的流程,小程序获取用户微信号就操作成功了,这项操作最主要的用处其实是将微信用户的信息融到小程序本身的功能和业务上去,更多相关资料请关注微信小程序商店。

  

  小程序获取公众号文章怎么弄?

  微信小程序获取接口实现轮播图怎么弄

  怎么获取别人的Appid小程序?获取appid的步骤