小程序中 能获取用户手机号信息,通过解密或者请求API得到真实的手机号码。
public ActionResult pay(string jscode,string encryptedData, string iv,string phonecode)
{
bool bosucceed = true;
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 = request_url(_url, _posdata);
if (_data.Contains("\"openid\""))
{
string _ip = Request.ServerVariables.Get("Remote_Addr").ToString().Trim();
dynamic _modal = Newtonsoft.Json.Linq.JToken.Parse(_data) as dynamic;
string _openid = _modal.openid;
string _session_key = _modal.session_key;
string _telPhone ="";
if(!String.IsNullOrEmpty(encryptedData) && !string.IsNullOrEmpty(IV))
{
//解析手机号码
_telPhone = getPhoneNumber(encryptedData, IV, _session_key);
}
if (!string.IsNullOrEmpty(phonecode) && string.IsNullOrEmpty(_telPhone))
{
#region 先获取access_token,再获取手机号码
//https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getAccessToken.html
_url = "https://api.weixin.qq.com/cgi-bin/token";
_posdata = "grant_type=client_credential&appid=" + appid + "&secret=" + secret + "";
Dictionary<string, string> dc = new Dictionary<string, string>();
dc.Add("grant_type", "client_credential");
dc.Add("appid", appid);
dc.Add("secret", secret);
bool succeed = false;
var token_res = PayCls.posdata(_url, dc, ref succeed, 1);
if (succeed)
{
dynamic token_data = Newtonsoft.Json.Linq.JToken.Parse(token_res) as dynamic;
if (token_data.access_token != null && token_data.access_token != "")
{
#region 获取手机号码
//https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-info/phone-number/getPhoneNumber.html
string access_token = Convert.ToString(token_data.access_token);
_url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + access_token;
dc = new Dictionary<string, string>();
dc.Add("code", phonecode);
succeed = false;
var phone_res = PayCls.posdata(_url, dc, ref succeed, 0);
if (succeed)
{
dynamic phone_data = Newtonsoft.Json.Linq.JToken.Parse(phone_res) as dynamic;
if (phone_data.errcode == "0")
{
try
{
Dictionary<string, object> phonelist = JsonConvert.DeserializeObject<Dictionary<string, object>>(Convert.ToString(phone_data.phone_info));
if (phonelist.ContainsKey("phoneNumber"))
{
_telPhone = phonelist["phoneNumber"].ToString().Trim();
}
else if (phonelist.ContainsKey("purePhoneNumber"))
{
_telPhone = phonelist["purePhoneNumber"].ToString().Trim();
}
}
catch (Exception ex)
{
string errmsg = ex.Message;
}
//{ "errcode":0,"errmsg":"ok","phone_info":{ "phoneNumber":"1595900xxxx","purePhoneNumber":"1595900xxxx","countryCode":"86","watermark":{ "timestamp":1690529517,"appid":"wx093fe96d62d9a278"} } }
}
}
#endregion
}
}
#endregion
}
}
}
catch (Exception ex)
{
return this.Json(new { succeed = false, data = ex.Message }, JsonRequestBehavior.AllowGet);
}
}
//https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.htm
/// <summary>
/// AES解密:从小程序中 getPhoneNumber 返回值中,解析手机号码
/// </summary>
/// <param name="encryptedData">包括敏感数据在内的完整用户信息的加密数据,详细见加密数据解密算法</param>
/// <param name="IV">加密算法的初始向量</param>
/// <param name="Session_key"></param>
/// <returns>手机号码</returns>
private string getPhoneNumber(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)
{
//MessageBox.Show(ex.Message);
return "";
}
}
#region 请求api
/// <summary>
/// 请求api
/// </summary>
/// <param name="_url"></param>
/// <param name="post_data"></param>
/// <returns></returns>
private string request_url(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;
}
#endregion
/// <summary>
///
/// </summary>
/// <param name="dpayUrl"></param>
/// <param name="dc"></param>
/// <param name="succeed"></param>
/// <param name="datatype">请求参数格式:0=application/json,1=application/x-www-form-urlencoded</param>
/// <returns></returns>
public static string posdata(string dpayUrl, Dictionary<string, string> dc, ref bool succeed, int datatype)
{
return posdata(dpayUrl, dc, ref succeed, 0, "", datatype);
}
/// <summary>
///
/// </summary>
/// <param name="dpayUrl"></param>
/// <param name="dc"></param>
/// <param name="succeed"></param>
/// <param name="postFrom"></param>
/// <param name="header"></param>
/// <param name="datatype">请求参数格式:0=application/json,1=application/x-www-form-urlencoded</param>
/// <returns></returns>
public static string posdata(string dpayUrl, Dictionary<string, string> dc, ref bool succeed, int postFrom, string header, int datatype)
{
if (dpayUrl.ToUpper().StartsWith("HTTPS"))
{
//https请求
//using System.Net.Security;
//using System.Security.Cryptography.X509Certificates;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);
}
string APIURL = dpayUrl;
string Receive = "";
try
{
using (var http = new HttpClient())
{
string jsonString = JsonConvert.SerializeObject(dc);
HttpContent content;
if (datatype == 0)
{
content = new StringContent(jsonString);
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");//application/json
}
else
{
content = new FormUrlEncodedContent(dc);//dc
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-www-form-urlencoded");
}
Receive = http.PostAsync(APIURL, content).Result.Content.ReadAsStringAsync().Result;
http.Dispose();
}
succeed = true;
}
catch (Exception ex)
{
succeed = false;
Receive = ex.Message;
}
return Receive;
}
public static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true;
}