微信小程序登錄獲取手機號 后台C#流程代碼


最近在做這個登錄功能接口,記錄一下

 

1、小程序端調用wx.login方法獲取code,后端使用WeChatAuth方法請求auth.code2Session接口使用appid、secret、js_code、grant_type:默認authorization_code獲取session_key、openid

auth.code2Session官方地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html

2、后端通過redis保存session_key、openid自定義登錄狀態並返回小程序端(也可以直接將兩個參數傳回小程序端,但是不安全)

3、小程序端使用button讓用戶進行授權獲取到encryptedData、iv加密數據和自定義狀登錄狀態傳回后端WeChatAuthUserInfo方法,判斷登錄狀態

4、后端使用Decrypt方法將加密數據進行解密,並反序列化為PhoneInfo類獲取到手機號進行數據庫操作

 

  1 /// <summary>
  2         /// 微信小程序-獲取登陸憑證code
  3         /// </summary>
  4         /// <param name="_"></param>
  5         /// <returns></returns>
  6         public Response WeChatAuth(dynamic _)
  7         {
  8 
  9             WechatLoginInfo req = this.GetReq<WechatLoginInfo>();
 10             string Auth_code = req.code;
 11             if (string.IsNullOrEmpty(Auth_code))
 12             {
 13                 return Fail("未獲取到Auth_code");
 14             }
 15             string AppId = Config.GetValue("WeChatAppId");
 16             string AppSecret = Config.GetValue("WeChatAppSecret");
 17 
 18 
 19             WebClient wc = new WebClient();
 20             wc.Encoding = System.Text.Encoding.UTF8;
 21 
 22 
 23             //第一步:通過code換取網頁授權access_token
 24             NameValueCollection tokennvc = new NameValueCollection();
 25             tokennvc.Add("appid", AppId);
 26             tokennvc.Add("secret", AppSecret);
 27             tokennvc.Add("js_code", Auth_code);
 28             tokennvc.Add("grant_type", "authorization_code");
 29             string tokenresult = System.Text.Encoding.UTF8.GetString(wc.UploadValues("https://api.weixin.qq.com/sns/jscode2session?", tokennvc));
 30             if (tokenresult.Contains("errcode"))
 31             {
 32                 AccessError accessError = Newtonsoft.Json.JsonConvert.DeserializeObject<AccessError>(tokenresult);
 33                 return Fail(accessError.errmsg);
 34             }
 35        //反序列化
 36             AuthAccessToken auth = Newtonsoft.Json.JsonConvert.DeserializeObject<AuthAccessToken>(tokenresult);
 37 
 38             TimeSpan ts = new TimeSpan(48, 0, 0);
 39             string token_session = Guid.NewGuid().ToString();
 40 
 41             //寫入Redis
 42             redisCache.Write<AuthAccessToken>("token_session_"+ token_session, auth, ts, CacheId.client);
 43 
 44             return Success(token_session);
 45         }
 49          77 
 78         /// <summary>
 79         /// 根據微信小程序平台提供的解密算法解密數據
 80         /// </summary>
 81         /// <param name="encryptedData">加密數據</param>
 82         /// <param name="iv">初始向量</param>
 83         /// <param name="sessionKey">從服務端獲取的SessionKey</param>
 84         /// <returns></returns>
 85         public PhoneInfo Decrypt(WechatLoginInfo loginInfo,string session_key)
 86         {
 87 
 88             //創建解密器生成工具實例
 89             AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
 90 
 91             //設置解密器參數
 92 
 93             aes.Mode = CipherMode.CBC;
 94 
 95             aes.BlockSize = 128;
 96 
 97             aes.Padding = PaddingMode.PKCS7;
 98 
 99             //格式化待處理字符串
100 
101             byte[] byte_encryptedData = Convert.FromBase64String(loginInfo.encryptedData);
102 
103             byte[] byte_iv = Convert.FromBase64String(loginInfo.iv);
104 
105             byte[] byte_sessionKey = Convert.FromBase64String(session_key);
106 
107             aes.IV = byte_iv;
108 
109             aes.Key = byte_sessionKey;
110 
111             //根據設置好的數據生成解密器實例
112 
113             ICryptoTransform transform = aes.CreateDecryptor();
114 
115             //解密
116 
117             byte[] final = transform.TransformFinalBlock(byte_encryptedData, 0, byte_encryptedData.Length);
118 
119             //生成結果
120 
121             string result = Encoding.UTF8.GetString(final);
122 
123             //反序列化結果,生成用戶信息實例
124 
125            var phoneInfo = Newtonsoft.Json.JsonConvert.DeserializeObject<PhoneInfo>(result);
126 
127             return phoneInfo;
128 
129         }
130 
131 
132         /// <summary>
133         /// 獲取微信小程序用戶信息
134         /// </summary>
135         /// <param name="_">The .</param>
136         /// <returns></returns>
137         public Response WeChatAuthUserInfo(dynamic _)
138         {
139             WechatLoginInfo req = this.GetReq<WechatLoginInfo>();
140             var AuthLogin = redisCache.Read<AuthAccessToken>("token_session_"+req.token_session, CacheId.clientuser);
141             if (AuthLogin== null)
142             {
143                 return Fail("找不到登錄密鑰");
144             }
145 
146             //數據解密,解密手機號等重要信息
147             PhoneInfo userinfojson = Decrypt(req,AuthLogin.session_key);
148 
149             if (userinfojson==null)
150             {
151                 return Fail("數據解密失敗");
152             }
153 
154             string Token = Guid.NewGuid().ToString().Substring(0,8);
156 string UserId = ""; 157 158 #region 159 //查詢數據庫userinfo是否有openid(沒有的話insert,有的話更新)openid是微信用戶唯一標識符
160 if (userinfo != null) 161 { 162 userinfo.Phone = userinfojson.phoneNumber; 163 userinfo.OpenId = AuthLogin.openid; 164 //進行update實例userinfo 165 UserId = userinfo.Id; 166 } 167 else 168 { 169 //進行insert entity171 entity.Nick_Name = Nick_Name; 172 entity.Phone = userinfojson.phoneNumber; 173 entity.OpenId = AuthLogin.openid;176 177 UserId = entity.Id; 178 } 179 //UserInfo實例類 180 UserInfo userentity = new UserInfo(); 181 userentity.Id = UserId; 182 userentity.Token = Token; 183 userentity.Nick_Name = Nick_Name; 184 userentity.Phone = userinfojson.phoneNumber; 185 userentity.AddTime = DateTime.Now; 186 userentity.OpenId = AuthLogin.openid; 187        //有效期 188 TimeSpan ts = new TimeSpan(48, 0, 0); 189 190 //寫入Redis 191 redisCache.Write<ResUserInfo>(Token, userentity, ts, CacheId.userinfo); 192 193 #endregion 194 195 return Success(userentity); 196 } 197 198 199 /// <summary> 200 /// 錯誤信息 201 /// </summary> 202 public class AccessError 203 { 204 /// <summary> 205 /// 錯誤碼 206 /// </summary> 207 public string errcode { get; set; } 208 /// <summary> 209 /// 錯誤信息 210 /// </summary> 211 public string errmsg { get; set; } 212 } 213 214 /// <summary> 215 /// 獲取AccessToken 216 /// </summary> 217 public class AuthAccessToken 218 { 219 //會話密鑰, 220 public string session_key { get; set; } 221 /// <summary> 222 /// access_token接口調用憑證超時時間,單位(秒) 223 /// </summary> 224 public string expires_in { get; set; } 225 /// <summary> 226 /// 獲取到的憑證 227 /// </summary> 228 public string access_token { get; set; } 229 /// <summary> 230 /// 用戶唯一標識,請注意,在未關注公眾號時,用戶訪問公眾號的網頁,也會產生一個用戶和公眾號唯一的OpenID 231 /// </summary> 232 public string openid { get; set; } 233 234 } 235 299 300 /// <summary> 301 /// 加密的數據 302 /// </summary> 303 public class Watermark 304 305 { 306 public string appid { get; set; } 307 308 public string timestamp { get; set; } 309 310 } 311 312 /// <summary> 313 /// 登錄獲取信息請求參數 314 /// </summary> 315 public class WechatLoginInfo 316 { 317 //自定義登錄狀態, 318 public string token_session { get; set; } 319 320 public string code { get; set; } 321 322 /// <summary> 323 ///加密數據 324 /// </summary> 325 /// <value> 326 /// </value> 327 public string encryptedData { get; set; } 328 329 /// <summary> 330 /// 加密算法的初始向量 331 /// </summary> 332 /// <value> 333 /// The iv. 334 /// </value> 335 public string iv { get; set; } 336 337 /// <summary> 338 /// 不包括敏感信息的原始數據字符串,用於計算簽名 339 /// </summary> 340 /// <value> 341 /// The raw data. 342 /// </value> 343 public WeChatUserInfo rawData { get; set; } 344 345 /// <summary> 346 /// 校驗用戶信息 347 /// </summary> 348 /// <value> 349 /// The signature. 350 /// </value> 351 public string signature { get; set; } 352 353 public WeChatUserInfo UserInfo { get; set; } 354 355 /// <summary> 356 /// 語言. 357 /// </summary> 358 /// <value> 359 /// The language. 360 /// </value> 361 public string language { get; set; } 362 363 } 364 365 /// <summary> 366 /// 手機號信息 367 /// </summary> 368 public class PhoneInfo 369 { 370 371 /// <summary> 372 /// 用戶的唯一標識 373 /// </summary> 374 public string openid { get; set; } 375 /// <summary> 376 /// 用戶綁定的手機號 377 /// </summary> 378 /// <value> 379 /// The phone number. 380 /// </value> 381 public string phoneNumber { get; set; } 382 /// <summary> 383 /// 沒有區號的手機號 384 /// </summary> 385 /// <value> 386 /// The pure phone number. 387 /// </value> 388 public string purePhoneNumber { get; set; } 389 /// <summary> 390 /// 區號 391 /// </summary> 392 /// <value> 393 /// The country code. 394 /// </value> 395 public string countryCode { get; set; } 396 397 398 public Watermark watermark { get; set; } 399 }

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM