最近在做一个小程序应用,需要让小程序获取用户openId和unionId,但是在这个过程中发现了一个问题,因为这个问题耽误了好久,不过最后还是找到了问题的根源。
问题:unionId有时候会获取不到!!!
原因:绑定了开发者账号的小程序,如果此开发者账号下存在同主体的公众号,用户没有关注该公众号,则无法获取到 unionId。当用户同时关注了该公众号,开发者可以直接通过 wx.login + code2Session 获取该用户 unionId。
下面直接贴上小程序授权登录获取用户openId和unionId的代码:
首先小程序端调用wx.login()发起登录,将code(票据)传递到java后台
小程序端
//授权用户信息
wx.login({
success: function (res) {
console.log(res);
if (res.code) {
wx.request({
url: "https://www.test.cn/miniprogram/miniLogin",
data: {
head: {},
body: {
code: res.code
}
},
method: "POST",
header: {
'content-type': 'application/json',
},
success: function (res) {
console.log(res);
},
fail: function (error) {
console.log(error);
}
})
}
},
fail: function (error) {
console.log(error);
}
})
Java后台
Java后台接收小程序端传过来的 code、encryptedData、iv 调用 code2Session 接口获取 openId,unionId 和 session_key
MiniProgramLogin 类
public class MiniProgramLogin {
// 小程序 AppID
private static final String appid = "xxxxxxxxxxxxxxxx";
// 小程序 AppSecret
private static final String secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
/**
* 小程序授权登录
*/
@RequestMapping(value="/miniLogin")
@ResponseBody
public Map<String,Object> miniLogin(String code, String encryptedData,String iv){
Map<String,Object> map=new HashMap<>();
String params = "appid=" + appid + "&secret=" + secret + "&js_code=" + code + "&grant_type=authorization_code";
String s=HttpUtil.sendGet("https://api.weixin.qq.com/sns/jscode2session", params);
JSONObject jsonObject = JSONObject.parseObject(s);
String session_key=jsonObject.getString("session_key");
String openid=jsonObject.getString("openid");
String unionid=jsonObject.getString("unionid");
String result=WXBizDataCrypt.decrypt1(encryptedData,session_key,iv);
JSONObject json=JSONObject.parseObject(result);
if (!StringUtils.isEmpty(result)&&result.length()>0){
String sex="";
if(json.getInteger("gender")==1){
sex="男";
}else if(json.getInteger("gender")==2){
sex="女";
}
if(unionid!=null){
map.put("unionid",unionid);
}else{
map.put("unionid",null);
}
map.put("session_key",session_key);
map.put("openid",openid);
map.put("avatarUrl",json.getString("avatarUrl"));
map.put("nickName",json.getString("nickName"));
map.put("sex",sex);
map.put("msg","success");
return map;
}
map.put("msg","error");
return map;
}
}
授权登录成功返回状态消息‘success’ ,授权不成功返回状态消息‘error’
HttpUtil Http响应工具类
public class HttpUtil {
/**
* 向指定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;
}
}
WXBizDataCrypt 解密工具类
public class WXBizDataCrypt {
/**
* AES解密
*
* @param data //密文,被加密的数据
* @param key //秘钥
* @param iv //偏移量
* @return
* @throws Exception
*/
public static String decrypt1(String data, String key,String iv){
//被加密的数据
byte[] dataByte = Base64.decodeBase64(data);
//加密秘钥
byte[] keyByte = Base64.decodeBase64(key);
//偏移量
byte[] ivByte = Base64.decodeBase64(iv);
try {
AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivByte);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(keyByte, "AES");
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
return new String(cipher.doFinal(dataByte),"UTF-8");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
}
下一篇文章:
Java-(二)微信小程序授权获取用户信息和手机号码