微信小程序 用户数据解密详细介绍


Posted in Javascript onJanuary 09, 2017

微信小程序 用户数据解密

官方指引图:

微信小程序 用户数据解密详细介绍

引导图一步一步操作

1、获取code

onLoad: function (options) {
  // 页面初始化 options为页面跳转所带来的参数
  let that = this
  wx.login({
   success: function (res) {
    // success
    let code = res.code
    that.setData({ code: code })
    wx.getUserInfo({
     success: function (res) {
      // success
      that.setData({ userInfo: res.userInfo })
      that.setData({ iv: res.iv })
      that.setData({ encryptedData: res.encryptedData })
      that.get3rdSession()
     }
    })
   }
 })
}

2、发送code到第三方服务器,获取3rd_session

get3rdSession:function(){
  let that = this
  wx.request({
   url: 'https://localhost:8443/get3rdSession',
   data: {
    code: this.data.code
   },
   method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
   // header: {}, // 设置请求的 header
   success: function (res) {
    // success
    var sessionId = res.data.session;
    that.setData({ sessionId: sessionId })
    wx.setStorageSync('sessionId', sessionId)
    that.decodeUserInfo()
   }
  })
 }

3、在第三方服务器上发送appid、appsecret、code到微信服务器换取session_key和openid

这里使用JFinal搭建的服务器

Redis配置

public void configPlugin(Plugins me) {
  //用于缓存userinfo模块的redis服务
  RedisPlugin userInfoRedis = new RedisPlugin("userInfo","localhost");
  me.add(userInfoRedis);
}

获取第三方session

public void get3rdSession() {
  //获取名为userInfo的Redis Cache对象
  Cache userInfoCache = Redis.use("userInfo");
  String sessionId = "";
  JSONObject json = new JSONObject();
  String code = getPara("code");
  String url = "https://api.weixin.qq.com/sns/jscode2session?appid=wx7560b8008e2c445d&secret=f1af3312b7038513fd17dd9cbc3b357c&js_code=" + code + "&grant_type=authorization_code";
  //执行命令生成3rd_session
  String session = ExecLinuxCMDUtil.instance.exec("cat /dev/urandom |od -x | tr -d ' '| head -n 1").toString();
  json.put("session", session);
  //创建默认的httpClient实例
  CloseableHttpClient httpClient = getHttpClient();
  try {
    //用get方法发送http请求
    HttpGet get = new HttpGet(url);
    System.out.println("执行get请求:...." + get.getURI());
    CloseableHttpResponse httpResponse = null;
    //发送get请求
    httpResponse = httpClient.execute(get);
    try {
      //response实体
      HttpEntity entity = httpResponse.getEntity();
      if (null != entity) {
        String result = EntityUtils.toString(entity);
        System.out.println(result);
        JSONObject resultJson = JSONObject.fromObject(result);
        String session_key = resultJson.getString("session_key");
        String openid = resultJson.getString("openid");
        //session存储
        userInfoCache.set(session,session_key+","+openid);
        }
      } finally {
        httpResponse.close();
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        closeHttpClient(httpClient);
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    renderJson(json);
}
private CloseableHttpClient getHttpClient() {
  return HttpClients.createDefault();
}

private void closeHttpClient(CloseableHttpClient client) throws IOException {
  if (client != null) {
    client.close();
  }
}

ExecLinuxCMDUtil.Java

import java.io.InputStreamReader;
import java.io.LineNumberReader;

/**
 * java在linux环境下执行linux命令,然后返回命令返回值。
 * Created by LJaer on 16/12/22.
 */
public class ExecLinuxCMDUtil {
  public static final ExecLinuxCMDUtil instance = new ExecLinuxCMDUtil();

  public static Object exec(String cmd) {
    try {
      String[] cmdA = { "/bin/sh", "-c", cmd };
      Process process = Runtime.getRuntime().exec(cmdA);
      LineNumberReader br = new LineNumberReader(new InputStreamReader(
          process.getInputStream()));
      StringBuffer sb = new StringBuffer();
      String line;
      while ((line = br.readLine()) != null) {
        System.out.println(line);
        sb.append(line).append("\n");
      }
      return sb.toString();
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }
}

4、解密用户数据

decodeUserInfo:function(){
  let that = this
  wx.request({
   url: 'https://localhost:8443/decodeUserInfo',
   data: {
    encryptedData: that.data.encryptedData,
    iv: that.data.iv,
    session: wx.getStorageSync('sessionId')
   },
   method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
   // header: {}, // 设置请求的 header
   success: function (res) {
    // success
    console.log(res)
   }
  })
}

console输出结果:

微信小程序 用户数据解密详细介绍

后端解密代码

/**
 * 解密用户敏感数据
 */
public void decodeUserInfo(){
  String encryptedData = getPara("encryptedData");
  String iv = getPara("iv");
  String session = getPara("session");
  //从缓存中获取session_key
  //获取名称为userInfo的Redis Cache对象
  Cache userInfoRedis = Redis.use("userInfo");
  Object wxSessionObj = userInfoRedis.get(session);
  if(null==wxSessionObj){
    renderNull();
  }
  String wxSessionStr = (String)wxSessionObj;
  String session_key = wxSessionStr.split(",")[0];


  try {
    byte[] resultByte = AESUtil.instance.decrypt(Base64.decodeBase64(encryptedData), Base64.decodeBase64(session_key), Base64.decodeBase64(iv));
    if(null != resultByte && resultByte.length > 0){
      String userInfo = new String(resultByte, "UTF-8");
      System.out.println(userInfo);
      JSONObject json = JSONObject.fromObject(userInfo); //将字符串{“id”:1}
      renderJson(json);
    }
  } catch (InvalidAlgorithmParameterException e) {
    e.printStackTrace();
  } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
  }
}

AESUtil.java

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.security.*;

public class AESUtil {
  public static final AESUtil instance = new AESUtil();

  public static boolean initialized = false;

  /**
   * AES解密
   * @param content 密文
   * @return
   * @throws InvalidAlgorithmParameterException
   * @throws NoSuchProviderException
   */
  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();
    }
    return null;
  }

  public static void initialize(){
    if (initialized) return;
    Security.addProvider(new BouncyCastleProvider());
    initialized = true;
  }
  //生成iv
  public static AlgorithmParameters generateIV(byte[] iv) throws Exception{
    AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
    params.init(new IvParameterSpec(iv));
    return params;
  }
}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

Javascript 相关文章推荐
js中opener与parent的区别详细解析
Jan 14 Javascript
基于JQuery实现的图片自动进行缩放和裁剪处理
Jan 31 Javascript
JavaScript中的console.log()函数详细介绍
Dec 29 Javascript
简单总结JavaScript中的String字符串类型
May 26 Javascript
用jQuery.ajaxSetup实现对请求和响应数据的过滤
Dec 20 Javascript
80%应聘者都不及格的JS面试题
Mar 21 Javascript
Dropify.js图片宽高自适应的方法
Nov 27 Javascript
如何在js代码中消灭for循环实例详解
Jul 29 Javascript
详解vue-router数据加载与缓存使用总结
Oct 29 Javascript
从理论角度讨论JavaScript闭包
Apr 03 Javascript
javascript中如何判断类型汇总
May 14 Javascript
操作按钮悬浮固定在微信小程序底部的实现代码
Aug 02 Javascript
微信小程序 摇一摇抽奖简单实例实现代码
Jan 09 #Javascript
jQuery实现弹出窗口弹出div层的实例代码
Jan 09 #Javascript
Bootstrap实现渐变顶部固定自适应导航栏
Aug 27 #Javascript
微信小程序 实战程序简易新闻的制作
Jan 09 #Javascript
jquery实现多次上传同一张图片
Jan 09 #Javascript
微信小程序 欢迎页面的制作(源码下载)
Jan 09 #Javascript
微信小程序 开发之快递查询功能的实现
Jan 09 #Javascript
You might like
PHP4与PHP5的时间格式问题
2008/02/17 PHP
ThinkPHP提交表单时默认自动转义的解决方法
2014/11/25 PHP
PHP中header函数的用法及其注意事项详解
2016/06/13 PHP
laravel框架与其他框架的详细对比
2019/10/23 PHP
php5.3/5.4/5.5/5.6/7常见新增特性汇总整理
2020/02/27 PHP
IE 缓存策略的BUG的解决方法
2007/07/21 Javascript
js怎么终止程序return不行换jfslk
2013/05/30 Javascript
javascript中apply和call方法的作用及区别说明
2014/02/14 Javascript
js实现文本框支持加减运算的方法
2015/08/19 Javascript
一个超简单的jQuery回调函数例子(分享)
2016/08/08 Javascript
Javascript中 带名 匿名 箭头函数的重要区别(推荐)
2017/01/29 Javascript
基于JS实现网页中的选项卡(两种方法)
2017/06/16 Javascript
ES6学习教程之模板字符串详解
2017/10/09 Javascript
vue 中 beforeRouteEnter 死循环的问题
2019/04/23 Javascript
JS事件流与事件处理程序实例分析
2019/08/16 Javascript
微信小程序实现pdf、word等格式文件上传的方法
2019/09/10 Javascript
JS实现点餐自动选择框(案例分析)
2019/12/10 Javascript
vue实现员工信息录入功能
2020/06/11 Javascript
vue路由切换时取消之前的所有请求操作
2020/09/01 Javascript
Openlayers学习之加载鹰眼控件
2020/09/28 Javascript
解决vue中使用less/sass及使用中遇到无效的问题
2020/10/24 Javascript
微信小程序实现弹幕墙(祝福墙)
2020/11/18 Javascript
[01:50]2014DOTA2西雅图邀请赛 专访欢乐周宝龙
2014/07/08 DOTA
python中函数总结之装饰器闭包详解
2016/06/12 Python
对Python 网络设备巡检脚本的实例讲解
2018/04/22 Python
python sklearn库实现简单逻辑回归的实例代码
2019/07/01 Python
深入了解Python enumerate和zip
2020/07/16 Python
CSS3属性使网站设计增强同时不消弱可用性
2009/08/29 HTML / CSS
美国珠宝网上商店:Jeulia
2016/09/01 全球购物
英国家用电器购物网站:Hughes
2018/02/23 全球购物
BNKR中国官网:带你感受澳洲领先潮流时尚
2018/08/21 全球购物
农村婚礼证婚词
2014/01/10 职场文书
机关党建工作汇报材料
2014/08/20 职场文书
2014年党员教师自我剖析材料
2014/09/30 职场文书
护理见习报告范文
2014/11/03 职场文书
springboot 全局异常处理和统一响应对象的处理方式
2022/06/28 Java/Android