微信小程序获取用户的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解不出来要去检查一下你的微信开放平台(微信开放平台)是否有绑定微信小程序。

 

posted @ 2018-11-20 16:21  21karat  阅读(1508)  评论(0编辑  收藏  举报