按照微信小程序官方文档,获取用户手机号分为2部分
微信小程序官网路径:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html
1.根据前端发送的code,根据微信提供的接口获取 session_key 和 openId
2.根据参数 session_key,vi,encrypted得到 用户手机号
使用微信小程序绑定所需要的依赖
<!--微信小程序,获取session_key所需依赖-->
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib-ext-spring</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
1:根据code获取session:
1.1:appSecret和appId是公司的,code是每次生成5分钟内有效
public Map<String,String> sessionKey(String code){
Map<String,String> map = new HashMap<>();
String result = "";
try{//请求微信服务器,用code换取openid。HttpUtil是工具类,后面会给出实现,Configure类是小程序配置信息,后面会给出代码
result = HttpUtils.doGet(
"https://api.weixin.qq.com/sns/jscode2session?appid="
+ appId + "&secret="
+ appSecret + "&js_code="
+ code
+ "&grant_type=authorization_code", null);
}
catch (Exception e) {
e.printStackTrace();
}
net.sf.json.JSONObject jsonObj = net.sf.json.JSONObject.fromObject(result);//解析从微信服务器上获取到的json字符串
System.out.println("用户的openid为:"+jsonObj.get("openid"));//此处也可以得到session_key的值
System.out.println("用户的session_key为:"+jsonObj.get("session_key"));
map.put("sessionKey",jsonObj.get("session_key").toString());
map.put("openId",jsonObj.get("openid").toString());
return map;
}
httpUtils工具类: 调用微信提供接口
public static String doGet(String urlPath, HashMap<String, Object> params)
throws Exception {
StringBuilder sb = new StringBuilder(urlPath);
if (params != null && !params.isEmpty()) { // 说明有参数
sb.append("?");
Set<Map.Entry<String, Object>> set = params.entrySet();
for (Map.Entry<String, Object> entry : set) { // 遍历map里面的参数
String key = entry.getKey();
String value = "";
if (null != entry.getValue()) {
value = entry.getValue().toString();
// 转码
value = URLEncoder.encode(value, "UTF-8");
}
sb.append(key).append("=").append(value).append("&");
}
sb.deleteCharAt(sb.length() - 1); // 删除最后一个&
}
// System.out.println(sb.toString());
URL url = new URL(sb.toString());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000); // 5s超时
conn.setRequestMethod("GET");
if (conn.getResponseCode() == HttpStatus.SC_OK) {// HttpStatus.SC_OK ==
// 200
BufferedReader reader = new BufferedReader(new InputStreamReader(
conn.getInputStream()));
StringBuilder sbs = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sbs.append(line);
}
// JSONObject jsonObject = new JSONObject(sbs.toString());
return sbs.toString();
}
return null;
}
实体类:
public class WxConstant {
//appid
public static final String appid = "";
//appsecret
public static final String secret = "";
public static final String authApi = "https://api.weixin.qq.com/sns/jscode2session";
public static final String AES = "AES";
public static final String AES_CBC_PADDING = "AES/CBC/PKCS7Padding";
}
以上是获取session_key 和 openId 代码
以下是获取用户手机号:
1.前端传递过来的 encrypted和iv (注意:前端生成的iv每次都不一样)
2.wxEntity是我自己封装的 如果用请求参数
例子:https://127.0.0.1:8000/mini/register?session_key=ulLsFyKlCfie8xgdPYebNQ&encrypted=“4CALAdX4HxmqBHR4m8xsxFIlJ8TLRNL3eV4uMghMa2cyuEbWM9qgpGAXT/8H9Kq23ytAQrcoUwY5Zdsk0It1IN0SDLF1KBdBwOr8OPcYQMN2Ff8313QAUSbwwnF02NVFHMQVMC9+v4gjOdZgImvAn5xdy9m6+ocw3G76+HBju/jTzInLJQoN8GQAZJ6OokbZcI0Kl7kx/Ur5iFnN22dgWg==”&iv=+sqy0eKrknPdL11UjN340g==
传递时:+或者空格 会进行转义,导致传递参数改变,所以我这里使用 json合适传递
String obj = WxUtils.wxDecrypt(EncryptedData(),sessionKey,Iv());
net.sf.json.JSONObject jsonObject = net.sf.json.JSONObject.fromObject(obj);
String phoneNumber = jsonObject.getString("phoneNumber");
System.out.println("phoneNumber:"+phoneNumber);
wxUtils:
public static String wxDecrypt(String encrypted, String session_key, String iv) {
String result = null;
byte[] encrypted64 = Base64.decodeBase64(encrypted);
byte[] key64 = Base64.decodeBase64(session_key);
byte[] iv64 = Base64.decodeBase64(iv);
// 如果密钥不足16位,那么就补足. 这个if 中的内容很重要
int base = 16;
if (key64.length % base != 0) {
int groups = key64.length / base
+ (key64.length % base != 0 ? 1 : 0);
byte[] temp = new byte[groups * base];
Arrays.fill(temp, (byte) 0);
System.arraycopy(key64, 0, temp, 0, key64.length);
key64 = temp;
}
try {
init();
result = new String(decrypt(encrypted64, key64, generateIV(iv64)));
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* * 初始化密钥
*
*/
public static void init() throws Exception {
Security.addProvider(new BouncyCastleProvider());
KeyGenerator.getInstance(WxConstant.AES).init(128);
}
/**
* * 生成iv
*
*/
public static AlgorithmParameters generateIV(byte[] iv) throws Exception {
// iv 为一个 16 字节的数组,这里采用和 iOS 端一样的构造方法,数据全为0
// Arrays.fill(iv, (byte) 0x00);
AlgorithmParameters params = AlgorithmParameters.getInstance(WxConstant.AES);
params.init(new IvParameterSpec(iv));
return params;
}
/**
* * 生成解密
*
*/
public static byte[] decrypt(byte[] encryptedData, byte[] keyBytes, AlgorithmParameters iv)
throws Exception {
Key key = new SecretKeySpec(keyBytes, WxConstant.AES);
Cipher cipher = Cipher.getInstance(WxConstant.AES_CBC_PADDING);
// 设置为解密模式
cipher.init(Cipher.DECRYPT_MODE, key, iv);
return cipher.doFinal(encryptedData);
}
以上就是实现微信绑定的代码,如果有不对的地方,请多指教