微信小程序獲取手機號,后端JAVA解密流程代碼
小程序獲取手機號,后端JAVA解密流程代碼
微信官方文檔獲取手機號流程地址,先看下最好方便理解下面步驟
實現(xiàn)思路,步驟如下
1.前端需先調(diào)用官方wx.login接口獲取登錄憑證code。
2.后端接收code 調(diào)用官方接口地址獲取用戶秘鑰 sessionKey。
3.前端通過官方getPhoneNumber獲取encryptedData,iv
4.前端通過參數(shù)**【encryptedData】 、【iv】 、【sessionKey】** 發(fā)送請求后端接口,解密用戶手機號
小程序獲取sessionkey詳細接口文檔
后端工作如下,
- 1.參數(shù)code 解密出sessionKey
- {“session_key”:“eF9PAi5P7ZbSaQqkGzEY5g==”,“openid”:“otJ1I4zMSFGDtk7C33O_h6U3IRK8”}
- 2.參數(shù)sessionKey,iv,encryptedData 解密出手機號
代碼如下:
下面工具類很全,放心代碼必須全,良心教程。
業(yè)務代碼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 {
//測試數(shù)據(jù)code
// js_code = "081ZQ3f91fr9VM1HYdb91y93f91ZQ3fU";
//微信獲取session_key接口地址
String wxLoginUrl = "https://api.weixin.qq.com/sns/jscode2session";
//接口參數(shù)
String param = "appid=小程序id&secret=小程序secret&js_code=" + js_code + "&grant_type=authorization_code";
//調(diào)用獲取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);
}
/**
* 解密小程序用戶敏感數(shù)據(jù)
*
* @param encryptedData 明文
* @param iv 加密算法的初始向量
* @param sessionKey 用戶秘鑰
* @return
*/
@ResponseBody
@PostMapping(value = "/decodeUserInfo")
@ApiImplicitParams({
@ApiImplicitParam(name = "encryptedData", value = "包括敏感數(shù)據(jù)在內(nèi)的完整用戶信息的加密數(shù)據(jù)",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();
//調(diào)用AESUtils工具類decrypt方法解密獲取json串
byte[] resultByte = aes.decrypt(Base64.decodeBase64(encryptedData), Base64.decodeBase64(sessionKey), Base64.decodeBase64(iv));
//判斷返回參數(shù)是否為空
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發(fā)送GET方法的請求
*
* @param url
* 發(fā)送請求的URL
* @param param
* 請求參數(shù),請求參數(shù)應該是 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("發(fā)送GET請求出現(xiàn)異常!" + e);
e.printStackTrace();
}
// 使用finally塊來關閉輸入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
/**
* 向指定 URL 發(fā)送POST方法的請求
*
* @param url
* 發(fā)送請求的 URL
* @param param
* 請求參數(shù),請求參數(shù)應該是 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)");
// 發(fā)送POST請求必須設置如下兩行
conn.setDoOutput(true);
conn.setDoInput(true);
// 獲取URLConnection對象對應的輸出流
out = new PrintWriter(conn.getOutputStream());
// 發(fā)送請求參數(shù)
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("發(fā)送 POST 請求出現(xiàn)異常!"+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定義工具類 防止有些朋友發(fā)現(xiàn)沒有這個類
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 = "返回數(shù)據(jù)")
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解密流程代碼的詳細內(nèi)容,更多關于微信小程序獲取手機號的資料請關注腳本之家其它相關文章!
相關文章
Java SSM框架(Spring+SpringMVC+MyBatis)搭建過程
最近一段時間搭建了ssm環(huán)境,并測試了幾個小項目,下面小編通過圖文并茂的形式給大家分享Java SSM框架(Spring+SpringMVC+MyBatis)搭建過程,需要的朋友參考下吧2017-11-11
Spring ApplicationListener的使用詳解
這篇文章主要介紹了Spring ApplicationListener的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-06-06

