Java-(一)微信小程序实现授权登录获取openId和unionId

最近在做一个小程序应用,需要让小程序获取用户openIdunionId,但是在这个过程中发现了一个问题,因为这个问题耽误了好久,不过最后还是找到了问题的根源。

问题: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-(二)微信小程序授权获取用户信息和手机号码

你可能感兴趣的:(微信开发,java)