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


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刷新框架子页面的七种方法代码
Nov 20 Javascript
jQuery Pagination Ajax分页插件(分页切换时无刷新与延迟)中文翻译版
Jan 11 Javascript
JavaScript 和 Java 的区别浅析
Jul 31 Javascript
javascript中的原型链深入理解
Feb 24 Javascript
js中的caller和callee属性介绍和例子
Jun 07 Javascript
DOM基础教程之使用DOM
Jan 19 Javascript
JavaScript缓冲运动实现方法(2则示例)
Jan 08 Javascript
jquery分隔Url的param方法(推荐)
May 25 Javascript
js中常用的Tab切换效果(推荐)
Aug 30 Javascript
javascript 数组去重复(在线去重工具)
Dec 17 Javascript
如何解决.vue文件url引用文件的问题
Jan 18 Javascript
JS实现省市县三级下拉联动
Apr 10 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环境搭建最新方法
2006/09/05 PHP
基于PHP选项与信息函数的使用详解
2013/05/10 PHP
php统计时间和内存使用情况示例分享
2014/03/13 PHP
thinkphp实现发送邮件密码找回功能实例
2014/12/01 PHP
php实现的生成迷宫与迷宫寻址算法完整实例
2017/11/06 PHP
Yii 实现数据加密和解密
2021/03/09 PHP
jquery实现的树形目录实例
2015/06/26 Javascript
jquery实现定时自动轮播特效
2015/12/10 Javascript
JavaScript中Window对象的属性及事件
2015/12/25 Javascript
Bootstrap插件全集
2016/07/18 Javascript
Highcharts入门之简介
2016/08/02 Javascript
Angularjs中$http以post请求通过消息体传递参数的实现方法
2016/08/05 Javascript
js面向对象编程总结
2017/02/16 Javascript
详细分析jsonp的原理和实现方式
2017/11/20 Javascript
vue router总结 $router和$route及router与 router与route区别
2019/07/05 Javascript
ES10的13个新特性示例(小结)
2019/09/23 Javascript
Vue.js页面中有多个input搜索框如何实现防抖操作
2019/11/04 Javascript
详解ES6新增字符串扩张方法includes()、startsWith()、endsWith()
2020/05/12 Javascript
Python编写检测数据库SA用户的方法
2014/07/11 Python
使用11行Python代码盗取了室友的U盘内容
2018/10/23 Python
python将字符串以utf-8格式保存在txt文件中的方法
2018/10/30 Python
浅谈python标准库--functools.partial
2019/03/13 Python
俄罗斯游戏商店:Buka
2020/03/01 全球购物
网络安全方面的面试题
2016/01/07 面试题
vue+django实现下载文件的示例
2021/03/24 Vue.js
应届大专毕业生个人自荐信
2013/09/22 职场文书
财政专业求职信范文
2014/02/19 职场文书
预备党员对照检查材料思想汇报
2014/09/24 职场文书
个人查摆问题整改措施
2014/10/04 职场文书
倡议书作文
2015/01/19 职场文书
自主招生英文自荐信
2015/03/25 职场文书
上市公司董事长岗位职责
2015/04/16 职场文书
python实现批量提取指定文件夹下同类型文件
2021/04/05 Python
《最终幻想14》6.01版本4月5日推出 追加新任务新道具
2022/04/03 其他游戏
python中 .npy文件的读写操作实例
2022/04/14 Python
Win10服务主机占用内存怎么办?Win10服务主机进程占用大量内存解决方法
2022/09/23 数码科技