public string GetPhoneNumber(string jscode, string encryptedData, string iv, string appid, string secret)
{
try
{
string _posdata = "appid=" + appid + "&secret=" + secret + "&js_code=" + jscode + "&grant_type=authorization_code";
string _url = "https://api.weixin.qq.com/sns/jscode2session";//获取openid
string _data = RequestUrl(_url, _posdata);
if (_data.Contains("\"openid\""))
{
dynamic _modal = Newtonsoft.Json.Linq.JToken.Parse(_data) as dynamic;
string _openid = _modal.openid;
string _session_key = _modal.session_key;
if (!String.IsNullOrEmpty(encryptedData) && !string.IsNullOrEmpty(iv))
{
//解析手机号码
string _telPhone = DecryptPhoneNumber(encryptedData, iv, _session_key);
return _telPhone;
}
}
return "未获取到手机号";
}
catch (Exception ex)
{
return ex.Message;
}
}
/// <summary>
/// 请求api
/// </summary>
/// <param name="_url"></param>
/// <param name="post_data"></param>
/// <returns></returns>
private string RequestUrl(string _url, string post_data)
{
string result = ""; string url = _url;// "https://api.weixin.qq.com/sns/jscode2session";
Encoding encoding = Encoding.UTF8;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.ContentType = "application/json";
//request.Headers=""
request.Method = "POST";
byte[] buffer = encoding.GetBytes(post_data.Trim());
request.ContentLength = buffer.Length;
request.GetRequestStream().Write(buffer, 0, buffer.Length);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
{
result = reader.ReadToEnd();
}
return result;
}
/// <summary>
/// AES解密:从小程序中 getPhoneNumber 返回值中,解析手机号码
/// </summary>
/// <param name="encryptedData">包括敏感数据在内的完整用户信息的加密数据,详细见加密数据解密算法</param>
/// <param name="IV">加密算法的初始向量</param>
/// <param name="Session_key"></param>
/// <returns>手机号码</returns>
private string DecryptPhoneNumber(string encryptedData, string IV, string Session_key)
{
try
{
byte[] encryData = Convert.FromBase64String(encryptedData); // strToToHexByte(text);
RijndaelManaged rijndaelCipher = new RijndaelManaged();
rijndaelCipher.Key = Convert.FromBase64String(Session_key); // Encoding.UTF8.GetBytes(AesKey);
rijndaelCipher.IV = Convert.FromBase64String(IV);// Encoding.UTF8.GetBytes(AesIV);
rijndaelCipher.Mode = CipherMode.CBC;
rijndaelCipher.Padding = PaddingMode.PKCS7;
ICryptoTransform transform = rijndaelCipher.CreateDecryptor();
byte[] plainText = transform.TransformFinalBlock(encryData, 0, encryData.Length);//出错处
string result = Encoding.Default.GetString(plainText);
//动态解析result 成对象
dynamic model = Newtonsoft.Json.Linq.JToken.Parse(result) as dynamic;
return model.phoneNumber;
}
catch (Exception ex)
{
return ex.Message;
}
}
这个方法其实还是挺好用的,但偶尔(大概20次有1次)报错。
提示错误:Padding is invalid and cannot be removed.
网上比较靠谱的说法是 盛派 的:
https://github.com/JeffreySu/WeiXinMPSDK/issues/1869
毕竟人家做这个是专业。
那也就是说,在 onload 或者 onshow 里面 就应该 wx.login 得到 code或者 session_key.
-------------------------------------------------------------------------------------------
正确获取手机号码的方法参见另一篇: