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


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 相关文章推荐
JavaScript 函数式编程的原理
Oct 16 Javascript
JS中toFixed()方法引起的问题如何解决
Nov 20 Javascript
在js文件中如何获取basePath处理js路径问题
Jul 10 Javascript
jQuery文字提示与图片提示效果实现方法
Jul 04 Javascript
Bootstrap 网格系统布局详解
Mar 19 Javascript
深入浅析nuxt.js基于ssh的vue通用框架
May 21 Javascript
JS实现点击生成UUID的方法完整实例【基于jQuery】
Jun 12 jQuery
Vue调用后端java接口的实例代码
Oct 28 Javascript
JavaScript中的相等操作符使用详解
Dec 21 Javascript
关于引入vue.js 文件的知识点总结
Jan 28 Javascript
JavaScript实现栈结构Stack过程详解
Mar 07 Javascript
Vue项目结合Vue-layer实现弹框式编辑功能(实例代码)
Mar 11 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
PHP实现过滤掉非汉字字符只保留中文字符
2015/06/04 PHP
php实现数组中索引关联数据转换成json对象的方法
2015/07/08 PHP
PHP命名空间和自动加载类
2016/04/03 PHP
PHP处理bmp格式图片的方法分析
2017/07/04 PHP
JCalendar 日历控件 v1.0 beta[兼容IE&Firefox] 有文档和例子
2007/05/30 Javascript
jQuery下的几个你可能没用过的功能
2010/08/29 Javascript
js定时器的使用(实例讲解)
2014/01/06 Javascript
JavaScript异步编程Promise模式的6个特性
2014/04/03 Javascript
JavaScript中使用Object.prototype.toString判断是否为数组
2015/04/01 Javascript
ECMAScript5(ES5)中bind方法使用小结
2015/05/07 Javascript
详解JavaScript中this的指向问题
2017/01/20 Javascript
angularjs中使用ng-bind-html和ng-include的实例
2017/04/28 Javascript
vue2手机APP项目添加开屏广告或者闪屏广告
2017/11/28 Javascript
JavaScript高级函数应用之分时函数实例分析
2018/08/03 Javascript
解决vue的变量在settimeout内部效果失效的问题
2018/08/30 Javascript
基于原生js实现判断元素是否有指定class名
2020/07/11 Javascript
vue elementui tree 任意级别拖拽功能代码
2020/08/31 Javascript
[01:31:22]DOTA2-DPC中国联赛定级赛 LBZS vs Magma BO3第二场 1月10日
2021/03/11 DOTA
编程语言Python的发展史
2014/09/26 Python
Python对象转JSON字符串的方法
2016/04/27 Python
python使用os.listdir和os.walk获得文件的路径的方法
2017/12/16 Python
Python深度优先算法生成迷宫
2018/01/22 Python
django 删除数据库表后重新同步的方法
2018/05/27 Python
java中的控制结构(if,循环)详解
2019/06/26 Python
python ffmpeg任意提取视频帧的方法
2020/02/21 Python
Django自定义列表 models字段显示方式
2020/04/03 Python
python实现PolynomialFeatures多项式的方法
2021/01/06 Python
python gui开发——制作抖音无水印视频下载工具(附源码)
2021/02/07 Python
KIEHL’S科颜氏官方旗舰店:源自美国的顶级护肤品牌
2018/06/07 全球购物
财务管理专业毕业生求职信范文
2013/09/21 职场文书
学生会干部自我鉴定2014
2014/09/18 职场文书
领导班子四风问题对照检查材料
2014/09/27 职场文书
建筑工程材料员岗位职责
2015/04/11 职场文书
领导干部学习三严三实心得体会
2016/01/05 职场文书
MySQL 隔离数据列和前缀索引的使用总结
2021/05/14 MySQL
oracle删除超过N天数据脚本的方法
2022/02/28 Oracle