微信小程式登錄獲取手機號 後臺C#流程代碼

来源:https://www.cnblogs.com/nimen/archive/2022/03/28/16068508.html
-Advertisement-
Play Games

最近在做這個登錄功能介面,記錄一下 1、小程式端調用wx.login方法獲取code,後端使用WeChatAuth方法請求auth.code2Session介面使用appid、secret、js_code、grant_type:預設authorization_code獲取session_key、op ...


最近在做這個登錄功能介面,記錄一下

 

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,寫入9號庫
 42             redisCache.Write<AuthAccessToken>("WeChatLogin_"+ token_session, auth, ts, CacheId.clientuser);
 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>("WeChatLogin_"+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();
155             string Nick_Name = "微信用戶_" + Token.Substring(0, 8);
156             string UserId = "";
157 
158             #region
159             U_UserEntity userinfo = u_UserBLL.GetEntityByOpenId(AuthLogin.openid);
160             if (userinfo != null)
161             {
162                 userinfo.Phone = userinfojson.phoneNumber;
163                 userinfo.OpenId = AuthLogin.openid;
164                 u_UserBLL.SaveEntity(userinfo.Id, userinfo);
165                 UserId = userinfo.Id;
166             }
167             else
168             {
169                 U_UserEntity entity = new U_UserEntity();
170                 entity.Id = Guid.NewGuid().ToString();
171                 entity.Nick_Name = Nick_Name;
172                 entity.Phone = userinfojson.phoneNumber;
173                 entity.OpenId = AuthLogin.openid;
174                 entity.AddTime = DateTime.Now;
175                 u_UserBLL.SaveEntity("", entity);
176 
177                 UserId = entity.Id;
178             }
179             
180             ResUserInfo userentity = new ResUserInfo();
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,寫入9號庫
191             redisCache.Write<ResUserInfo>(Token, userentity, ts, CacheId.clientuser);
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         }

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • package Day18; import java.util.Scanner; import java.util.Set; import java.util.TreeMap; /* * 分析: * A:首先鍵盤輸入一個字元串 * B:創建一個TreeMap集合 鍵唯一 鍵值覆蓋--自然排序 * C ...
  • 先看一段代碼: int i = 0; int a = i++; sout("a的值是:"+i); sout("i的值是:"+i); 最終的編譯之後的核心位元組碼如下 L0 BITPUSH 0 //將常量0壓入操作棧 ISTORE_1 //將當前棧頂元素,彈出並保存到局部變數表的slot_1中 L1 I ...
  • 首先 每個人都會有一段特別懷念而又難忘的時光吧,我到現在依然記得大學時光的美好。讓我們一起來懷念一下時光吧。今天這個故事從一張校園卡開始,相信很多小伙伴們都用過校園卡,它是一種其個人身份認證、校園消費、數據共用等多功能於一體的校園信息集成與管理系統。在它裡面存儲著大量的數據,包含:學生消費、宿舍門禁 ...
  • OAuth2客戶端按照它們與授權伺服器進行安全認證的能力可以分為機密類型(Confidential)和公共類型(Public)。 機密類型的自身會有個密碼憑據,比如Web伺服器後端程式;而公共類型則沒有密碼憑據,純瀏覽器前端應用或者移動客戶端應用大都屬於這一種類型。不管是哪一種,它們都有客戶端ID( ...
  • 一、LinkedList集合特有的方法 方法名說明 public void addFirst(E e) 在該鏈表的頭部插入指定的元素 public void addLast(E e) 在該鏈表的尾部追加指定的元素 public E getLast() 返回此鏈表的最後一個元素 public E ge ...
  • 對於spring-security來說,當你訪問一個受保護資源時,需要檢查你的token,當沒有傳遞,或者傳遞的token有錯誤時,將出現401unauthorized異常;當你傳遞的token是有效的,但解析後並沒有訪問這個資源的許可權時,將返回403forbidden的異常,而你通過攔截器@Res ...
  • 最終版:07_中證網(Plus -Pro).py # coding=utf-8 import requests from bs4 import BeautifulSoup import io import sys import os sys.stdout = io.TextIOWrapper(sys ...
  • 上文,我們通過剖析一個最簡單的 Blazor WASM 項目,講明白了 Razor 文件是什麼,以及它被轉譯成 C#後長什麼樣子。也介紹了 Razor 中最簡單的一個語法:Razor Expression,也就是 Razor 表達式 本文將介紹兩個內容: 首先我們將書接上文,再介紹一丁點 Razor ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...