微信小程序獲取用戶的unionId以及手機號


  • 后端接口入參:
  1. code :臨時登錄憑證(必傳)
  2. encryptedData:密文
  3. iv:偏移量
  • 控制層接口:
 1 @Action(value = "findWx")
 2 public void findWx() throws IOException {
 3         System.out.println("開始");
 4         //小程序返回登錄相關信息(自定義返回給小程序的信息)
 5         RequestWxAppMsg msg = new RequestWxAppMsg();
 6         msg.setCode(AppActionResultCode.CODE_FAILURE);
 7         System.out.println("wxcode:" + code);
 8         System.out.println("encryptedData:" + encryptedData);
 9         System.out.println("iv:" + iv);
10         /*======================================================*/
11         //登錄憑證不能為空
12         if (code == null || code.length() == 0) {
13             msg.setCode(AppActionResultCode.CODE_FAILURE);
14             System.out.println("登錄憑證不能為空");
15         }
16         //小程序唯一標識   (在微信小程序管理后台獲取)
17         String wxspAppid = "***************";
18         //小程序的 app secret (在微信小程序管理后台獲取)
19         String wxspSecret = "***************";
20         //授權(必填)
21         String grant_type = code;
22         /*========1、向微信服務器 使用登錄憑證 code 獲取 session_key 和 openid=========*/
23         //請求參數
24         String params = "appid=" + wxspAppid + "&secret=" + wxspSecret + "&js_code=" + code + "&grant_type=" + grant_type;
25         //發送請求
26         String sr = HttpRequest.sendGet("https://api.weixin.qq.com/sns/jscode2session", params);
27         //解析相應內容(轉換成json對象)
28         JSONObject json = JSONObject.fromObject(sr);
29         //獲取會話密鑰(session_key)
30         String session_key = json.get("session_key").toString();
31         //用戶的唯一標識(openid)
32         String openid = (String) json.get("openid");
33         //返回的數據
34         msg.setOpenId(openid);
35         System.out.println("請求成功獲取openId以及會話密鑰(如果不需要unionId以及手機號此刻可以直接結束返回openId)");
36         /*=========2、對encryptedData加密數據進行AES解密(unionId)========================*/
37         try {
38             String result = AesCbcUtil.decrypt(encryptedData, session_key, iv, "UTF-8");
39             System.out.println("解密結果:"+result);
40             if (null != result && result.length() > 0) {
41                 JSONObject userInfoJSON = JSONObject.fromObject(result);
42                 //返回的數據
43                 msg.setUnionId((String) userInfoJSON.get("unionId"));
44                 msg.setCode(AppActionResultCode.CODE_SUCCESS);
45             }
46         } catch (Exception e) {
47             e.printStackTrace();
48         }
49         /*=========2、對encryptedData加密數據進行AES解密(phone)========================*/
50         try {
51             String phone = AuthLoginUtil.getPhone(encryptedData,session_key,iv);
52             if(!phone.equals("")){
53                 msg.setPhone(phone);
54             }
55         } catch (InvalidAlgorithmParameterException e) {
56             // TODO Auto-generated catch block
57             e.printStackTrace();
58         }
59         doOutput(msg);
60 }
View Code
  • 發送請求的工具類HttpRequest:
  1 import java.io.BufferedReader;
  2 import java.io.IOException;
  3 import java.io.InputStreamReader;
  4 import java.io.PrintWriter;
  5 import java.net.URL;
  6 import java.net.URLConnection;
  7 import java.util.List;
  8 import java.util.Map;
  9 
 10 public class HttpRequest{
 11     public static void main(String[] args) {
 12         //發送 GET 請求
 13         String s=HttpRequest.sendGet("http://v.qq.com/x/cover/kvehb7okfxqstmc.html?vid=e01957zem6o", "");
 14         System.out.println(s);
 15         //發送 POST 請求
 16         //String sr=HttpRequest.sendPost("http://www.toutiao.com/stream/widget/local_weather/data/?city=%E4%B8%8A%E6%B5%B7", "");
 17         //JSONObject json = JSONObject.fromObject(sr);
 18         //System.out.println(json.get("data"));
 19     }
 20     /**
 21      * 向指定URL發送GET方法的請求
 22      * 
 23      * @param url
 24      *            發送請求的URL
 25      * @param param
 26      *            請求參數,請求參數應該是 name1=value1&name2=value2 的形式。
 27      * @return URL 所代表遠程資源的響應結果
 28      */
 29     public static String sendGet(String url, String param) {
 30         String result = "";
 31         BufferedReader in = null;
 32         try {
 33             String urlNameString = url + "?" + param;
 34             URL realUrl = new URL(urlNameString);
 35             // 打開和URL之間的連接
 36             URLConnection connection = realUrl.openConnection();
 37             // 設置通用的請求屬性
 38             connection.setRequestProperty("accept", "*/*");
 39             connection.setRequestProperty("connection", "Keep-Alive");
 40             connection.setRequestProperty("user-agent",
 41                     "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
 42             // 建立實際的連接
 43             connection.connect();
 44             // 獲取所有響應頭字段
 45             Map<String, List<String>> map = connection.getHeaderFields();
 46             // 遍歷所有的響應頭字段
 47             for (String key : map.keySet()) {
 48                 System.out.println(key + "--->" + map.get(key));
 49             }
 50             // 定義 BufferedReader輸入流來讀取URL的響應
 51             in = new BufferedReader(new InputStreamReader(
 52                     connection.getInputStream()));
 53             String line;
 54             while ((line = in.readLine()) != null) {
 55                 result += line;
 56             }
 57         } catch (Exception e) {
 58             System.out.println("發送GET請求出現異常!" + e);
 59             e.printStackTrace();
 60         }
 61         // 使用finally塊來關閉輸入流
 62         finally {
 63             try {
 64                 if (in != null) {
 65                     in.close();
 66                 }
 67             } catch (Exception e2) {
 68                 e2.printStackTrace();
 69             }
 70         }
 71         return result;
 72     }
 73 
 74     /**
 75      * 向指定 URL 發送POST方法的請求
 76      * 
 77      * @param url
 78      *            發送請求的 URL
 79      * @param param
 80      *            請求參數,請求參數應該是 name1=value1&name2=value2 的形式。
 81      * @return 所代表遠程資源的響應結果
 82      */
 83     public static String sendPost(String url, String param) {
 84         PrintWriter out = null;
 85         BufferedReader in = null;
 86         String result = "";
 87         try {
 88             URL realUrl = new URL(url);
 89             // 打開和URL之間的連接
 90             URLConnection conn = realUrl.openConnection();
 91             // 設置通用的請求屬性
 92             conn.setRequestProperty("accept", "*/*");
 93             conn.setRequestProperty("connection", "Keep-Alive");
 94             conn.setRequestProperty("user-agent",
 95                     "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
 96             // 發送POST請求必須設置如下兩行
 97             conn.setDoOutput(true);
 98             conn.setDoInput(true);
 99             // 獲取URLConnection對象對應的輸出流
100             out = new PrintWriter(conn.getOutputStream());
101             // 發送請求參數
102             out.print(param);
103             // flush輸出流的緩沖
104             out.flush();
105             // 定義BufferedReader輸入流來讀取URL的響應
106             in = new BufferedReader(
107                     new InputStreamReader(conn.getInputStream()));
108             String line;
109             while ((line = in.readLine()) != null) {
110                 result += line;
111             }
112         } catch (Exception e) {
113             System.out.println("發送 POST 請求出現異常!"+e);
114             e.printStackTrace();
115         }
116         //使用finally塊來關閉輸出流、輸入流
117         finally{
118             try{
119                 if(out!=null){
120                     out.close();
121                 }
122                 if(in!=null){
123                     in.close();
124                 }
125             }
126             catch(IOException ex){
127                 ex.printStackTrace();
128             }
129         }
130         return result;
131     }
132 }
View Code
  • 解密unionId的工具類AesCbcUtil:
 1 import org.apache.commons.codec.binary.Base64;
 2 import org.bouncycastle.jce.provider.BouncyCastleProvider;
 3 import javax.crypto.BadPaddingException;
 4 import javax.crypto.Cipher;
 5 import javax.crypto.IllegalBlockSizeException;
 6 import javax.crypto.NoSuchPaddingException;
 7 import javax.crypto.spec.IvParameterSpec;
 8 import javax.crypto.spec.SecretKeySpec;
 9 import java.io.UnsupportedEncodingException;
10 import java.security.*;
11 import java.security.spec.InvalidParameterSpecException;
12 
13 public class AesCbcUtil {
14 
15     static {
16         Security.addProvider(new BouncyCastleProvider());
17     }
18 
19     /**
20      * AES解密
21      *
22      * @param data           //密文,被加密的數據
23      * @param key            //秘鑰
24      * @param iv             //偏移量
25      * @param encodingFormat //解密后的結果需要進行的編碼
26      * @return
27      * @throws Exception
28      */
29     public static String decrypt(String data, String key, String iv, String encodingFormat) throws Exception {
30         //被加密的數據
31         byte[] dataByte = Base64.decodeBase64(data);
32         //加密秘鑰
33         byte[] keyByte = Base64.decodeBase64(key);
34         //偏移量
35         byte[] ivByte = Base64.decodeBase64(iv);
36         try {
37             Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
38 
39             SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
40 
41             AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
42             parameters.init(new IvParameterSpec(ivByte));
43 
44             cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
45 
46             byte[] resultByte = cipher.doFinal(dataByte);
47             if (null != resultByte && resultByte.length > 0) {
48                 String result = new String(resultByte, encodingFormat);
49                 return result;
50             }
51             return null;
52         } catch (NoSuchAlgorithmException e) {
53             e.printStackTrace();
54         } catch (NoSuchPaddingException e) {
55             e.printStackTrace();
56         } catch (InvalidParameterSpecException e) {
57             e.printStackTrace();
58         } catch (InvalidKeyException e) {
59             e.printStackTrace();
60         } catch (InvalidAlgorithmParameterException e) {
61             e.printStackTrace();
62         } catch (IllegalBlockSizeException e) {
63             e.printStackTrace();
64         } catch (BadPaddingException e) {
65             e.printStackTrace();
66         } catch (UnsupportedEncodingException e) {
67             e.printStackTrace();
68         }
69 
70         return null;
71     }
72 
73 }
View Code
  • 解密手機號的工具類AuthLoginUtil:
 1 import java.io.UnsupportedEncodingException;
 2 import java.security.InvalidAlgorithmParameterException;
 3 import org.apache.tomcat.util.codec.binary.Base64;
 4 import com.alibaba.fastjson.JSON;
 5 import com.alibaba.fastjson.JSONObject;
 6 
 7 public class AuthLoginUtil {
 8     //解密得到電話號碼
 9     public static String getPhone(String encryptedData,String sessionKey,String iv) throws InvalidAlgorithmParameterException, UnsupportedEncodingException{
10         String phone="";
11         byte[] resultByte = AES.decrypt(Base64.decodeBase64(encryptedData),
12                 Base64.decodeBase64(sessionKey),
13                 Base64.decodeBase64(iv));
14         if (null != resultByte && resultByte.length > 0) {
15             String userInfo = new String(resultByte, "UTF-8");         
16             System.out.println(userInfo);
17             JSONObject userJson =JSON.parseObject(userInfo);
18             phone = userJson.getString("phoneNumber");
19             System.out.println("電話:"+phone);
20             //解密成功
21             System.out.println("解密成功");
22         } else {
23             System.out.println("解密報錯");
24         }
25         return phone;
26     }
27 }
View Code
  • 參考博客:
  1. https://blog.csdn.net/wujin274/article/details/76604964
  2. https://zhuanlan.zhihu.com/p/25124713
  •  注:解密手機號與unionId分別寫在2個接口中(解密的入參不同),unionId解不出來要去檢查一下你的微信開放平台(微信開放平台)是否有綁定微信小程序。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM