首頁 微信小程式 小程式開發 微信小程式之後台解密用戶資料的範例分享

微信小程式之後台解密用戶資料的範例分享

May 15, 2018 am 11:03 AM
小程式 數據 使用者

這篇文章主要介紹了微信小程式後台解密使用者資料實例詳解的相關資料,需要的朋友可以參考下

 微信小程式後台解密使用者資料實例詳解

#openId : 使用者在目前小程式的唯一識別 

因為最近根據API呼叫https://api.weixin.qq.com/sns/jscode2session所以需要設定以下服務,但是官方是不贊成這種做法的,
而且最近把在伺服器配置的方法給關閉了。也就是說要取得使用者openid,地區等資訊只能在後台取得。

一下是官方的流程

那麼問題來了,程式碼怎麼實作呢,以下是用java後台的實作

微信客戶端的程式碼實作是這樣的

wx.login({ 
   success: function (r) { 
    if (r.code) { 
     var code = r.code;//登录凭证 
     if (code) { 
      //2、调用获取用户信息接口 
      wx.getUserInfo({ 
       success: function (res) { 
        //发起网络请求 
        wx.request({ 
         url: that.data.net + '/decodeUser.json', 
         header: { 
          "content-type": "application/x-www-form-urlencoded" 
         }, 
         method: "POST", 
         data: { 
          encryptedData: res.encryptedData, 
          iv: res.iv, 
          code: code 
         }, 
         success: function (result) { 
          // wx.setStorage({ 
          //  key: 'openid', 
          //  data: res.data.openid, 
          // }) 
          console.log(result) 
         } 
        }) 
       }, 
       fail: function () { 
        console.log('获取用户信息失败') 
       } 
      }) 
     } else { 
      console.log('获取用户登录态失败!' + r.errMsg) 
     } 

    } else { 
    } 
   } 
  })
登入後複製

(服務端java)自己的伺服器傳送code到微信伺服器取得openid(使用者唯一識別)和session_key(會話金鑰),
最後將encryptedData、iv 、session_key透過AES解密取得到使用者敏感資料

1、取得密碼金鑰並處理解密的controller

/** 
   * 解密用户敏感数据 
   * 
   * @param encryptedData 明文,加密数据 
   * @param iv      加密算法的初始向量 
   * @param code     用户允许登录后,回调内容会带上 code(有效期五分钟),开发者需要将 code 发送到开发者服务器后台,使用code 换取 session_key api,将 code 换成 openid 和 session_key 
   * @return 
   */ 
  @ResponseBody 
  @RequestMapping(value = "/decodeUser", method = RequestMethod.POST) 
  public Map decodeUser(String encryptedData, String iv, String code) { 

    Map map = new HashMap(); 

    //登录凭证不能为空 
    if (code == null || code.length() == 0) { 
      map.put("status", 0); 
      map.put("msg", "code 不能为空"); 
      return map; 
    } 

    //小程序唯一标识  (在微信小程序管理后台获取) 
    String wxspAppid = "wxd8980e77d335c871"; 
    //小程序的 app secret (在微信小程序管理后台获取) 
    String wxspSecret = "85d29ab4fa8c797423f2d7da5dd514cf"; 
    //授权(必填) 
    String grant_type = "authorization_code"; 


    //////////////// 1、向微信服务器 使用登录凭证 code 获取 session_key 和 openid //////////////// 
    //请求参数 
    String params = "appid=" + wxspAppid + "&secret=" + wxspSecret + "&js_code=" + code + "&grant_type=" + grant_type; 
    //发送请求 
    String sr = HttpRequest.sendGet("https://api.weixin.qq.com/sns/jscode2session", params); 
    //解析相应内容(转换成json对象) 
    JSONObject json = JSONObject.fromObject(sr); 
    //获取会话密钥(session_key) 
    String session_key = json.get("session_key").toString(); 
    //用户的唯一标识(openid) 
    String openid = (String) json.get("openid"); 

    //////////////// 2、对encryptedData加密数据进行AES解密 //////////////// 
    try { 
      String result = AesCbcUtil.decrypt(encryptedData, session_key, iv, "UTF-8"); 
      if (null != result && result.length() > 0) { 
        map.put("status", 1); 
        map.put("msg", "解密成功"); 

        JSONObject userInfoJSON = JSONObject.fromObject(result); 
        Map userInfo = new HashMap(); 
        userInfo.put("openId", userInfoJSON.get("openId")); 
        userInfo.put("nickName", userInfoJSON.get("nickName")); 
        userInfo.put("gender", userInfoJSON.get("gender")); 
        userInfo.put("city", userInfoJSON.get("city")); 
        userInfo.put("province", userInfoJSON.get("province")); 
        userInfo.put("country", userInfoJSON.get("country")); 
        userInfo.put("avatarUrl", userInfoJSON.get("avatarUrl")); 
        userInfo.put("unionId", userInfoJSON.get("unionId")); 
        map.put("userInfo", userInfo); 
        return map; 
      } 
    } catch (Exception e) { 
      e.printStackTrace(); 
    } 
    map.put("status", 0); 
    map.put("msg", "解密失败"); 
    return map; 
  }
登入後複製

解密工具類別AesCbcUtil

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; 

/** 
 * Created by lsh 
 * 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 { 
//    initialize(); 

    //被加密的数据 
    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; 
  } 

}
登入後複製

發送請求的工具類別HttpRequest

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.URL; 
import java.net.URLConnection; 
import java.util.List; 
import java.util.Map; 

/** 
 * Created by lsh on 2017/6/22. 
 */ 
public class HttpRequest { 
  /** 
   * 向指定URL发送GET方法的请求 
   * 
   * @param url 
   *      发送请求的URL 
   * @param param 
   *      请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 
   * @return URL 所代表远程资源的响应结果 
   */ 
  public static String sendGet(String url, String param) { 
    String result = ""; 
    BufferedReader in = null; 
    try { 
      String urlNameString = url + "?" + param; 
      URL realUrl = new URL(urlNameString); 
      // 打开和URL之间的连接 
      URLConnection connection = realUrl.openConnection(); 
      // 设置通用的请求属性 
      connection.setRequestProperty("accept", "*/*"); 
      connection.setRequestProperty("connection", "Keep-Alive"); 
      connection.setRequestProperty("user-agent", 
          "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); 
      // 建立实际的连接 
      connection.connect(); 
      // 获取所有响应头字段 
      Map<String, List<String>> map = connection.getHeaderFields(); 
      // 遍历所有的响应头字段 
      for (String key : map.keySet()) { 
        System.out.println(key + "--->" + map.get(key)); 
      } 
      // 定义 BufferedReader输入流来读取URL的响应 
      in = new BufferedReader(new InputStreamReader( 
          connection.getInputStream())); 
      String line; 
      while ((line = in.readLine()) != null) { 
        result += line; 
      } 
    } catch (Exception e) { 
      System.out.println("发送GET请求出现异常!" + e); 
      e.printStackTrace(); 
    } 
    // 使用finally块来关闭输入流 
    finally { 
      try { 
        if (in != null) { 
          in.close(); 
        } 
      } catch (Exception e2) { 
        e2.printStackTrace(); 
      } 
    } 
    return result; 
  } 

  /** 
   * 向指定 URL 发送POST方法的请求 
   * 
   * @param url 
   *      发送请求的 URL 
   * @param param 
   *      请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 
   * @return 所代表远程资源的响应结果 
   */ 
  public static String sendPost(String url, String param) { 
    PrintWriter out = null; 
    BufferedReader in = null; 
    String result = ""; 
    try { 
      URL realUrl = new URL(url); 
      // 打开和URL之间的连接 
      URLConnection conn = realUrl.openConnection(); 
      // 设置通用的请求属性 
      conn.setRequestProperty("accept", "*/*"); 
      conn.setRequestProperty("connection", "Keep-Alive"); 
      conn.setRequestProperty("user-agent", 
          "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); 
      // 发送POST请求必须设置如下两行 
      conn.setDoOutput(true); 
      conn.setDoInput(true); 
      // 获取URLConnection对象对应的输出流 
      out = new PrintWriter(conn.getOutputStream()); 
      // 发送请求参数 
      out.print(param); 
      // flush输出流的缓冲 
      out.flush(); 
      // 定义BufferedReader输入流来读取URL的响应 
      in = new BufferedReader( 
          new InputStreamReader(conn.getInputStream())); 
      String line; 
      while ((line = in.readLine()) != null) { 
        result += line; 
      } 
    } catch (Exception e) { 
      System.out.println("发送 POST 请求出现异常!"+e); 
      e.printStackTrace(); 
    } 
    //使用finally块来关闭输出流、输入流 
    finally{ 
      try{ 
        if(out!=null){ 
          out.close(); 
        } 
        if(in!=null){ 
          in.close(); 
        } 
      } 
      catch(IOException ex){ 
        ex.printStackTrace(); 
      } 
    } 
    return result; 
  } 
}
登入後複製

另外由於需求使用解密的工具類別所有要在pom檔案加上這個依賴

<dependency> 
  <groupId>org.bouncycastle</groupId> 
  <artifactId>bcprov-ext-jdk16</artifactId> 
  <version>1.46</version> 
  <type>jar</type> 
  <scope>compile</scope> 
</dependency>
登入後複製

這樣才能引入bcprov這個jar包。網路上參考了一下,個人感覺加這個依賴是最容易解決問題的。 

以上是微信小程式之後台解密用戶資料的範例分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何用小紅書號找出用戶?能查到手機號碼嗎? 如何用小紅書號找出用戶?能查到手機號碼嗎? Mar 22, 2024 am 08:40 AM

隨著社群媒體的迅速發展,小紅書已經成為了備受青睞的社群平台之一。用戶可以透過建立小紅書號來展示個人身份,並與其他用戶交流互動。如果你需要找某個用戶的小紅書號碼,可以按照以下簡單步驟來操作。一、如何用小紅書號找出用戶? 1.開啟小紅書APP,點選右下角的「發現」按鈕,然後選擇「筆記」選項。 2.在筆記清單中,找到你想找的用戶發布的筆記。點擊進入筆記詳情頁。 3.在筆記詳情頁中,點選使用者頭像下方的「追蹤」按鈕,即可進入該使用者的個人首頁。 4.在使用者個人主頁右上角,點選三個點按鈕,然後選擇「個人資訊

使用ddrescue在Linux上恢復數據 使用ddrescue在Linux上恢復數據 Mar 20, 2024 pm 01:37 PM

DDREASE是一種用於從檔案或區塊裝置(如硬碟、SSD、RAM磁碟、CD、DVD和USB儲存裝置)復原資料的工具。它將資料從一個區塊設備複製到另一個區塊設備,留下損壞的資料區塊,只移動好的資料區塊。 ddreasue是一種強大的恢復工具,完全自動化,因為它在恢復操作期間不需要任何干擾。此外,由於有了ddasue地圖文件,它可以隨時停止和恢復。 DDREASE的其他主要功能如下:它不會覆寫恢復的數據,但會在迭代恢復的情況下填補空白。但是,如果指示工具明確執行此操作,則可以將其截斷。將資料從多個檔案或區塊還原到單

以超級使用者登入Ubuntu 以超級使用者登入Ubuntu Mar 20, 2024 am 10:55 AM

在Ubuntu系統中,root使用者通常是停用狀態的。要啟動root用戶,可以使用passwd指令設定密碼,然後使用su-指令以root身分登入。根用戶是具有系統管理權限且不受限制的使用者。他擁有存取和修改檔案、使用者管理、軟體安裝和刪除,以及系統配置變更等權限。根用戶與一般用戶有著明顯的區別,根用戶擁有系統中最高的權限和更廣泛的控制權。根用戶可以執行重要的系統命令和編輯系統文件,而普通用戶則無法做到這一點。在本指南中,我將探討Ubuntu根用戶,如何以根用戶身份登錄,以及它與一般用戶的不同之處。注意

開源!超越ZoeDepth! DepthFM:快速且精確的單目深度估計! 開源!超越ZoeDepth! DepthFM:快速且精確的單目深度估計! Apr 03, 2024 pm 12:04 PM

0.這篇文章乾了啥?提出了DepthFM:一個多功能且快速的最先進的生成式單目深度估計模型。除了傳統的深度估計任務外,DepthFM還展示了在深度修復等下游任務中的最先進能力。 DepthFM效率高,可以在少數推理步驟內合成深度圖。以下一起來閱讀這項工作~1.論文資訊標題:DepthFM:FastMonocularDepthEstimationwithFlowMatching作者:MingGui,JohannesS.Fischer,UlrichPrestel,PingchuanMa,Dmytr

Google狂喜:JAX性能超越Pytorch、TensorFlow!或成GPU推理訓練最快選擇 Google狂喜:JAX性能超越Pytorch、TensorFlow!或成GPU推理訓練最快選擇 Apr 01, 2024 pm 07:46 PM

谷歌力推的JAX在最近的基準測試中表現已經超過Pytorch和TensorFlow,7項指標排名第一。而且測試並不是JAX性能表現最好的TPU上完成的。雖然現在在開發者中,Pytorch依然比Tensorflow更受歡迎。但未來,也許有更多的大型模型會基於JAX平台進行訓練和運行。模型最近,Keras團隊為三個後端(TensorFlow、JAX、PyTorch)與原生PyTorch實作以及搭配TensorFlow的Keras2進行了基準測試。首先,他們為生成式和非生成式人工智慧任務選擇了一組主流

iPhone上的蜂窩數據網路速度慢:修復 iPhone上的蜂窩數據網路速度慢:修復 May 03, 2024 pm 09:01 PM

在iPhone上面臨滯後,緩慢的行動數據連線?通常,手機上蜂窩互聯網的強度取決於幾個因素,例如區域、蜂窩網絡類型、漫遊類型等。您可以採取一些措施來獲得更快、更可靠的蜂窩網路連線。修復1–強制重啟iPhone有時,強制重啟設備只會重置許多內容,包括蜂窩網路連線。步驟1–只需按一次音量調高鍵並放開即可。接下來,按降低音量鍵並再次釋放它。步驟2–過程的下一部分是按住右側的按鈕。讓iPhone完成重啟。啟用蜂窩數據並檢查網路速度。再次檢查修復2–更改資料模式雖然5G提供了更好的網路速度,但在訊號較弱

特斯拉機器人進廠打工,馬斯克:手的自由度今年將達到22個! 特斯拉機器人進廠打工,馬斯克:手的自由度今年將達到22個! May 06, 2024 pm 04:13 PM

特斯拉機器人Optimus最新影片出爐,已經可以在工廠裡打工了。正常速度下,它分揀電池(特斯拉的4680電池)是這樣的:官方還放出了20倍速下的樣子——在小小的「工位」上,揀啊揀啊揀:這次放出的影片亮點之一在於Optimus在廠子裡完成這項工作,是完全自主的,全程沒有人為的干預。而且在Optimus的視角之下,它還可以把放歪了的電池重新撿起來放置,主打一個自動糾錯:對於Optimus的手,英偉達科學家JimFan給出了高度的評價:Optimus的手是全球五指機器人裡最靈巧的之一。它的手不僅有觸覺

超級智能體生命力覺醒!可自我更新的AI來了,媽媽再也不用擔心資料瓶頸難題 超級智能體生命力覺醒!可自我更新的AI來了,媽媽再也不用擔心資料瓶頸難題 Apr 29, 2024 pm 06:55 PM

哭死啊,全球狂煉大模型,一網路的資料不夠用,根本不夠用。訓練模型搞得跟《飢餓遊戲》似的,全球AI研究者,都在苦惱怎麼才能餵飽這群資料大胃王。尤其在多模態任務中,這問題尤其突出。一籌莫展之際,來自人大系的初創團隊,用自家的新模型,率先在國內把「模型生成數據自己餵自己」變成了現實。而且還是理解側和生成側雙管齊下,兩側都能產生高品質、多模態的新數據,對模型本身進行數據反哺。模型是啥?中關村論壇上剛露面的多模態大模型Awaker1.0。團隊是誰?智子引擎。由人大高瓴人工智慧學院博士生高一鑷創立,高

See all articles