c#小程序登录拿用户手机号数据

登录流程

	1.微信小程序端 通过 wx.login 拿到 需要post的 code.

	2. 一般情况下,通过getUserProfile可以拿到userInfo,拿到的userInfo是可视的,不需要解密就能post到后台的。

	3.但有时候需要通过getPhoneNumber  拿用户手机号 和iv值,拿到的手机号它是被加密了的手机号(encryptedData),这时候就需要把拿到的encryptedData 连同code 和iv 一起post到后台,由后台进行解密。

	4. 前端要 先进行wx.login  之后再进行getUserProfile 和 getPhoneNumber  操作   因为 wx.login 会刷新会话秘钥session_key ,如果wx.login 最后执行了  那么等于后台用新的session_key 去解旧的加密字段,很显然不行的, 就像前朝的尚方宝剑斩不了现在的官员。
	
	5.个人号没有获取用户手机号的权限,所以必须是服务号小程序才可以,所以个人号小程序 不要做无谓的挣扎 

后台控制器代码如下

不管你那边是怎么写的,重要的是拿到前端post的数据encryptedData,code 和iv
 [ApiController]
    [Route("/api/public/v1/users/")]
    public class UserController : Controller
    {
        private readonly ILogger<UserController> _logger;

        public UserController(ILogger<UserController> logger) {

            _logger = logger;
        }
        [Route("wxlogin")]
        [HttpPost]
        public async Task<IActionResult> wxlogin(string encryptedData,string code,string iv) {
	
            string Appid = appConf.Instance.APPID;//你的appid
            string Secret =appConf.Instance.SecretKey; 你的SecretKey
            string grant_type = "authorization_code";
            string re = await this.GetJsonStr();
            string url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + Appid + "&secret=" + Secret + "&js_code=" + code + "&grant_type=" + grant_type;
            try
            {
                string res = RESTClient.Get(url);//发Get请求拿到响应内容 ,RESTClient.cs 见后文//
            
             var jsonlist =  LitJson.JsonMapper.ToObject(res);//反序列化响应内容 
                string open_id = (string)jsonlist["openid"]; //拿openid
                string session_key = (string)jsonlist["session_key"];//拿session_key 
                if (!string.IsNullOrWhiteSpace(open_id)&& !string.IsNullOrWhiteSpace(session_key))
                {
                
                var result1 = WXToolKit.DecodeEncryptedData(session_key, encryptedData, iv);  代码走到这就行了,可以打印解密以后的result1 json字符串,查看解密结果是否正确。  没必要往下继续进行了,再往下也就是反序列化一下,拿到手机号码,多的不说了,自行发挥,咱们主要说解密的过程  解密代码都在下面的WXToolKit.cs工具类中

                /***************************************/
               
                }
                return JSONRES.success("");
            }
            catch (Exception e)
            {
                _logger.LogInformation(e.ToString());
                return "404";
            }
        }
  
    }

主要代码 WXToolKit.cs

  public class WXToolKit
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sessionKey"> </param>
        /// <param name="encryptedData"></param>
        /// <param name="iv"></param>
        /// <returns></returns>
        public static string DecodeEncryptedData(string sessionKey, string encryptedData, string iv)
            var aesKey = Convert.FromBase64String(sessionKey);
            var aesIV = Convert.FromBase64String(iv);

            var result = AES_Decrypt(encryptedData, aesIV, aesKey);
            var resultStr = Encoding.UTF8.GetString(result);
            return resultStr;
        }

        private static byte[] decode2(byte[] decrypted)
        {
            int pad = (int)decrypted[decrypted.Length - 1];
            if (pad < 1 || pad > 32)
            {
                pad = 0;
            }
            byte[] res = new byte[decrypted.Length - pad];
            Array.Copy(decrypted, 0, res, 0, decrypted.Length - pad);
            return res;
        }

   
        private static byte[] AES_Decrypt(String Input, byte[] Iv, byte[] Key)
        {
#if NET45
            RijndaelManaged aes = new RijndaelManaged();
#else
            SymmetricAlgorithm aes = Aes.Create();
#endif
            aes.KeySize = 128;//原始:256
            aes.BlockSize = 128;
            aes.Mode = CipherMode.CBC;
            aes.Padding = PaddingMode.PKCS7;
            aes.Key = Key;
            aes.IV = Iv;
            var decrypt = aes.CreateDecryptor(aes.Key, aes.IV);
            byte[] xBuff = null;

            try
            {
                using (var ms = new MemoryStream())
                {
                    using (var cs = new CryptoStream(ms, decrypt, CryptoStreamMode.Write))
                    {
                      
                        byte[] xXml = Convert.FromBase64String(Input);
                        byte[] msg = new byte[xXml.Length + 32 - xXml.Length % 32];
                        Array.Copy(xXml, msg, xXml.Length);
                        cs.Write(xXml, 0, xXml.Length);
                    }
                  
                    xBuff = decode2(ms.ToArray());
                }
            }
            catch (System.Security.Cryptography.CryptographicException)
            {
              
                using (var ms = new MemoryStream())
                {
                 
                    var cs = new CryptoStream(ms, decrypt, CryptoStreamMode.Write);
                    {
                      
                        byte[] xXml = Convert.FromBase64String(Input);
                        byte[] msg = new byte[xXml.Length + 32 - xXml.Length % 32];
                        Array.Copy(xXml, msg, xXml.Length);
                        cs.Write(xXml, 0, xXml.Length);
                    }
                    //cs.Dispose();
                    xBuff = decode2(ms.ToArray());
                }
            }
            return xBuff;
        }

      
    }

不重要代码 RESTClient.cs

  public class RESTClient
    {
        public static string Get(string url) {

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
         
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            using (StreamReader readStream = new StreamReader(response.GetResponseStream(), encoding:Encoding.UTF8))
            {                
                   return  readStream.ReadToEnd();   
            }

        }

        public static string Post(string url,string data) {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "POST";
            using (StreamWriter streamWriter= new StreamWriter(request.GetRequestStream()))
            {
                streamWriter.Write(data);
            }

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            using (StreamReader readStream = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
            {
                return readStream.ReadToEnd();
            }

        }

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值