微信公众号获取用户手机

关键坑点:

1. 不了解调用流程:流程->前台JS获取code-->post至后台api-->先获取session_key【调用微信api,返回json】-->解密手机号方法

2. 解密方法缺少包,需要不断添加包

3.解密方法没有问题,仍然无法获取,网上找资料清理缓存。问题解决。

 

第一步:wxml增加按钮

第二步:js文件调用后台

getPhoneNumber(e) {

console.log(e.detail.errMsg)

console.log(e.detail.iv)

var encryptedData = e.detail.encryptedData

console.log(encryptedData)

var code=""

var that = this;

console.log(e.detail.errMsg == "getPhoneNumber:ok");

if (e.detail.errMsg == "getPhoneNumber:ok") {

wx.login({

success: function (res) {

code = res.code

console.log("code_s")//这就是code

console.log( res.code)//这就是code

console.log("code_e")//这就是code

wx.request({

url: 'https://XXXXXXX',

method: "post",

header: {

'content-type': 'application/x-www-form-urlencoded;charset=utf-8'

},

data: {

encryptedData: e.detail.encryptedData,

iv: e.detail.iv,

code: res.code

},

 

success: function (res) {

console.log(res);

}

})

}

})

}

},

第三步:后台代码,分2步;第一步获取seesion_key;第二步解密手机号

Api服务方法

    @RequestMapping("/decodephone")
    public void  decodePhone(HttpServletRequest request, HttpServletResponse response,String encryptedData,String iv,String code){
        String mbody=StringUtils.ReadAsChars(request);
        System.out.println(mbody);
        String  msession_key= HttpUtil.doGet("https://api.weixin.qq.com/sns/jscode2session","appid=您的API的ID&secret=您的秘钥&js_code=前端传过来的CODE&grant_type=authorization_code");

        WeChatAppSessionModel mdl1=JSONObject.parseObject(msession_key, WeChatAppSessionModel.class);
        if(mdl1 !=null && mdl1.getSession_key()!=null)
        {
        try {
                mbody=AES.wxDecrypt(encryptedData, mdl1.getSession_key(), iv);
                response.getWriter().write("123");
            } catch (Exception e) {
                e.printStackTrace();
            }
        
        }
        System.out.println("调用结束");
    }

doGet 公共方法

 public static String doGet(String url,String parameter)
    {
        String uriAPI =url+"?"+parameter ; //"http://XXXXX?str=I+am+get+String";
        String result= "";
        HttpClient client = createSSLClientDefault();
        HttpGet httpRequst = new HttpGet(uriAPI);
        try {

            HttpResponse httpResponse = client.execute(httpRequst);//其中HttpGet是HttpUriRequst的子类
            if(httpResponse.getStatusLine().getStatusCode() == 200)
            {
                HttpEntity httpEntity = httpResponse.getEntity();
                result = EntityUtils.toString(httpEntity);//取出应答字符串
                // 一般来说都要删除多余的字符
                result.replaceAll("\r", "");//去掉返回结果中的"\r"字符,否则会在结果字符串后面显示一个小方格
            }
            else
                httpRequst.abort();
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            result = e.getMessage().toString();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            result = e.getMessage().toString();
        }
        return result;
    }

解密方法


import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.AlgorithmParameters;
import java.security.Key;
import java.security.Security;
 
public class AES {
  // 算法名
  public static final String KEY_NAME = "AES";
  // 加解密算法/模式/填充方式
  // ECB模式只用密钥即可对数据进行加密解密,CBC模式需要添加一个iv
  public static final String CIPHER_ALGORITHM = "AES/CBC/PKCS7Padding";
 
  /**
   * 微信 数据解密

   * 对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充

   * 对称解密的目标密文:encrypted=Base64_Decode(encryptData)

   * 对称解密秘钥:key = Base64_Decode(session_key),aeskey是16字节

   * 对称解密算法初始向量:iv = Base64_Decode(iv),同样是16字节

   *
   * @param encrypted 目标密文
   * @param session_key 会话ID
   * @param iv 加密算法的初始向量
   */
  public static String wxDecrypt(String encrypted, String session_key, String iv) {
    String json = null;
    byte[] encrypted64 = Base64.decodeBase64(encrypted);
    byte[] key64 = Base64.decodeBase64(session_key);
    byte[] iv64 = Base64.decodeBase64(iv);
    byte[] data;
    try {
      init();
      json = new String(decrypt(encrypted64, key64, generateIV(iv64)));
    } catch (Exception e) {
      e.printStackTrace();
    }
    return json;
  }
 
  /**
   * 初始化密钥
   */
  public static void init() throws Exception {
    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    KeyGenerator.getInstance(KEY_NAME).init(128);
  }
 
  /**
   * 生成iv
   */
  public static AlgorithmParameters generateIV(byte[] iv) throws Exception {
    // iv 为一个 16 字节的数组,这里采用和 iOS 端一样的构造方法,数据全为0
    // Arrays.fill(iv, (byte) 0x00);
    AlgorithmParameters params = AlgorithmParameters.getInstance(KEY_NAME);
    params.init(new IvParameterSpec(iv));
    return params;
  }
 
  /**
   * 生成解密
   */
  public static byte[] decrypt(byte[] encryptedData, byte[] keyBytes, AlgorithmParameters iv)
      throws Exception {
    Key key = new SecretKeySpec(keyBytes, KEY_NAME);
    Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
    // 设置为解密模式
    cipher.init(Cipher.DECRYPT_MODE, key, iv);
    return cipher.doFinal(encryptedData);
  }
 
}

你可能感兴趣的:(微信公众号获取用户手机)