微信小程序获取手机号,后端JAVA解密流程代码
小程序获取手机号,后端JAVA解密流程代码
微信官方文档获取手机号流程地址,先看下最好方便理解下面步骤
实现思路,步骤如下
1.前端需先调用官方wx.login接口获取登录凭证code。
2.后端接收code 调用官方接口地址获取用户秘钥 sessionKey。
3.前端通过官方getPhoneNumber获取encryptedData,iv
4.前端通过参数**【encryptedData】 、【iv】 、【sessionKey】** 发送请求后端接口,解密用户手机号
小程序获取sessionkey详细接口文档
后端工作如下,
- 1.参数code 解密出sessionKey
- {“session_key”:“eF9PAi5P7ZbSaQqkGzEY5g==”,“openid”:“otJ1I4zMSFGDtk7C33O_h6U3IRK8”}
- 2.参数sessionKey,iv,encryptedData 解密出手机号
代码如下:
下面工具类很全,放心代码必须全,良心教程。
业务代码Controller
package com.df.detection.controller; import com.df.detection.base.entity.ResultBean; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import org.apache.commons.codec.binary.Base64; import org.json.JSONException; import org.springframework.web.bind.annotation.*; import java.io.UnsupportedEncodingException; import java.security.InvalidAlgorithmParameterException; import org.json.JSONObject; /** * @Author Songzhongjin * @Date 2020/7/15 10:09 * @Version 1.0 */ @Api(value = "小程序登录授权 Controller",tags = {"小程序登录授权接口"}) @RestController @RequestMapping("/app") public class APPController { /** * 微信小程序登录获取 * 获取session_key * @param * @return */ @ResponseBody @PostMapping("/initWxLogin") @ApiImplicitParams({ @ApiImplicitParam(name = "js_code", value = "登录时获取的code",paramType = "form", dataType = "string", required = true) }) public ResultBeaninitWxLogin(@RequestParam(value = "js_code", required = true) String js_code) throws JSONException { //测试数据code // js_code = "081ZQ3f91fr9VM1HYdb91y93f91ZQ3fU"; //微信获取session_key接口地址 String wxLoginUrl = "https://api.weixin.qq.com/sns/jscode2session"; //接口参数 String param = "appid=小程序id&secret=小程序secret&js_code=" + js_code + "&grant_type=authorization_code"; //调用获取session_key接口 请求方式get String jsonString = GetPostUntil.sendGet(wxLoginUrl, param); System.out.println(jsonString); //因为json字符串是大括号包围,所以用JSONObject解析 JSONObject json = new JSONObject(jsonString); //json解析session_key值 String session_key = json.getString("session_key"); System.out.println("session_key:" + session_key); //返回给前端 return ResultBean.success("session_key",session_key); } /** * 解密小程序用户敏感数据 * * @param encryptedData 明文 * @param iv 加密算法的初始向量 * @param sessionKey 用户秘钥 * @return */ @ResponseBody @PostMapping(value = "/decodeUserInfo") @ApiImplicitParams({ @ApiImplicitParam(name = "encryptedData", value = "包括敏感数据在内的完整用户信息的加密数据",paramType = "form", dataType = "string", required = true), @ApiImplicitParam(name = "iv", value = "加密算法的初始向量",paramType = "form", dataType = "string", required = true), @ApiImplicitParam(name = "sessionKey", value = "用户秘钥",paramType = "form", dataType = "string", required = true) }) public ResultBean decodeUserInfo(@RequestParam(required = true, value = "encryptedData") String encryptedData, @RequestParam(required = true, value = "iv") String iv, @RequestParam(required = true, value = "sessionKey") String sessionKey ) throws UnsupportedEncodingException, InvalidAlgorithmParameterException, JSONException { //AESUtils微信获取手机号解密工具类 AESUtils aes = new AESUtils(); //调用AESUtils工具类decrypt方法解密获取json串 byte[] resultByte = aes.decrypt(Base64.decodeBase64(encryptedData), Base64.decodeBase64(sessionKey), Base64.decodeBase64(iv)); //判断返回参数是否为空 if (null != resultByte && resultByte.length > 0) { String jsons = new String(resultByte, "UTF-8"); System.out.println(jsons); JSONObject json = new JSONObject(jsons); //json解析phoneNumber值 String phoneNumber = json.getString("phoneNumber"); System.out.println("phoneNumber:" + phoneNumber); return ResultBean.success("手机号", phoneNumber); } return ResultBean.error(500,"session_key:失败"); } }
工具类代码如下
package com.df.detection.controller; 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; /** * @Author Songzhongjin * @Date 2020/7/15 10:37 * @Version 1.0 */ public class GetPostUntil { /** * 向指定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; } }
AESUtils工具类 解密手机号
package com.df.detection.controller; import org.apache.tomcat.util.codec.binary.Base64; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; 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 javax.xml.transform.Result; import java.security.*; /** * @Author Songzhongjin * @Date 2020/7/15 11:46 * @Version 1.0 */ public class AESUtils { 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; } }
接口返回对象ResultBean定义工具类 防止有些朋友发现没有这个类
package com.df.detection.base.entity; import io.swagger.annotations.ApiModelProperty; /** * @author Liu Yaoguang * @Classname aaa * @Description * @Date 2019/12/06 09:22 */ public class ResultBean<T> { @ApiModelProperty(value = "返回码",dataType = "int") private int code; @ApiModelProperty(value = "返回描述信息",dataType = "string") private String message; @ApiModelProperty(value = "返回数据") private T data; @ApiModelProperty(value = "口令",dataType = "string") private String token; private ResultBean() { } public static ResultBean error(int code, String message) { ResultBean resultBean = new ResultBean(); resultBean.setCode(code); resultBean.setMessage(message); return resultBean; } public static<T> ResultBean error(int code, String message,T data) { ResultBean resultBean = new ResultBean(); resultBean.setCode(code); resultBean.setMessage(message); resultBean.setData(data); return resultBean; } public static ResultBean success(String message) { ResultBean resultBean = new ResultBean(); resultBean.setCode(200); resultBean.setMessage(message); return resultBean; } public static<T> ResultBean success(String message,T data) { ResultBean resultBean = new ResultBean(); resultBean.setCode(200); resultBean.setMessage(message); resultBean.setData(data); return resultBean; } public static ResultBean success(String message,Object data,String token) { ResultBean resultBean = new ResultBean(); resultBean.setCode(200); resultBean.setMessage(message); resultBean.setData(data); resultBean.setToken(token); return resultBean; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public T getData() { return data; } public void setData(T data) { this.data = data; } public String getToken() { return token; } public void setToken(String token) { this.token = token; } }
以上就是微信小程序获取手机号,后端JAVA解密流程代码的详细内容,更多关于微信小程序获取手机号的资料请关注我们其它相关文章!
赞 (0)