.NET微信網頁開發之透過UnionID機制解決多應用使用者帳號統一問題

追逐時光者發表於2023-12-15

背景

隨著公司微信相關業務場景的不斷擴充,從最初的一個微信移動應用、然後發展成微信公眾號應用、然後又有了微信小程式應用。但是隨著應用的擴充,如何保證相同使用者的微信使用者在不同應用中登入的同一個賬號呢?今天的主題就來了.NET微信網頁開發之透過UnionID機制解決多應用使用者帳號統一問題。

UnionID 機制

如果開發者擁有多個移動應用、網站應用、和公眾賬號(包括小程式),可透過 UnionID 來區分使用者的唯一性,因為只要是同一個微信開放平臺賬號下的移動應用、網站應用和公眾賬號(包括小程式),使用者的 UnionID 是唯一的。換句話說,同一使用者,對同一個微信開放平臺下的不同應用,UnionID是相同的。

獲取使用者基本資訊(UnionID機制)

在關注者與公眾號產生訊息互動後,公眾號可獲得關注者的OpenID(加密後的微訊號,每個使用者對每個公眾號的OpenID是唯一的。對於不同公眾號,同一使用者的openid不同)。公眾號可透過對應介面來根據OpenID獲取使用者基本資訊,包括語言和關注時間。

請注意,如果開發者有在多個公眾號,或在公眾號、移動應用之間統一使用者賬號的需求,需要前往微信開放平臺(open.weixin.qq.com)繫結公眾號後,才可利用UnionID機制來滿足上述需求。

微信開放平臺配置

登入地址:https://open.weixin.qq.com/

微信公眾號微信登入配置

在基本配置中獲取微信公眾號的appid和appsecrect(一定是要自己公眾號的),白名單是你在本地除錯的微信專案的時候需要新增的你本地的ip地址,不然獲取不到你想要的accsee_token。

配置伺服器地址(url):這裡是你的專案與微信伺服器通訊的地方,一定不能填錯,Token是你專案中的,將其複製到這裡即可,訊息加密解密金鑰是微信端隨機生成的。

在微信公眾號設定設定對應業務域名,js介面安全域名,以及網頁授權域名:

 

微信網頁公眾號獲取使用者UnionID(使用者統一標識)

注意:使用者統一標識(針對一個微信開放平臺賬號下的應用,同一使用者的 unionid 是唯一的),只有當scope為"snsapi_userinfo"時返回

使用者同意授權獲取code

在確保微信公眾賬號擁有授權作用域(scope引數)的許可權的前提下(已認證服務號,預設擁有scope引數中的snsapi_base和snsapi_userinfo 許可權),引導關注者開啟如下頁面:

若提示“該連結無法訪問”,請檢查引數是否填寫錯誤,是否擁有scope引數對應的授權作用域許可權。跳轉回撥redirect_uri,應當使用https連結來確保授權code的安全性,並且是在微信公眾號後臺配置的網頁授權域名的訪問地址。

  • https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect

請求引數:

透過code獲取使用者UnionID(使用者統一標識)

  • 獲取code後,請求以下連結獲取access_token:https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

請求引數:

返回引數:

請求示例程式碼:

    public class WeChatLogin : Controller
    {

        /// <summary>
        /// 獲取使用者UnionID(使用者統一標識)
        /// </summary>
        /// <param name="state">自定義引數</param>
        /// <param name="code">透過使用者授權後得到的code</param>
        /// <returns></returns>
        public async Task<Response> GetWeChatUnionID(string state, string code)
        {
            string appId = "YourAppId";
            string appSecret = "YourAppSecret";
            string requestUrl = $"https://api.weixin.qq.com/sns/oauth2/access_token?appid={appId}&secret={appSecret}&code={code}&grant_type=authorization_code";

            using (var httpClient = new HttpClient())
            {
                var httpRequest = new HttpRequestMessage(HttpMethod.Get, requestUrl);
                using (var response = await httpClient.SendAsync(httpRequest))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        var responseString = await response.Content.ReadAsStringAsync();
                        var responseData = JsonConvert.DeserializeObject<WeChatTokenResponse>(responseString);

                        return new Response
                        {
                            Code = 1,
                            Message = responseData.UnionId
                        };
                    }
                    else
                    {
                        var errorResponseString = await response.Content.ReadAsStringAsync();
                        var errorData = JsonConvert.DeserializeObject<ErrorResponse>(errorResponseString);

                        return new Response
                        {
                            Code = 0,
                            Message = $"Failed to get access token: {errorData.ErrMsg}"
                        };
                    }
                }
            }
        }
    }

    public class WeChatTokenResponse
    {
        [JsonProperty("access_token")]
        public string AccessToken { get; set; }

        [JsonProperty("expires_in")]
        public int ExpiresIn { get; set; }

        [JsonProperty("refresh_token")]
        public string RefreshToken { get; set; }

        [JsonProperty("openid")]
        public string OpenId { get; set; }

        [JsonProperty("scope")]
        public string Scope { get; set; }

        [JsonProperty("is_snapshotuser")]
        public int IsSnapshotUser { get; set; }

        [JsonProperty("unionid")]
        public string UnionId { get; set; }
    }

    public class ErrorResponse
    {
        [JsonProperty("errcode")]
        public int ErrCode { get; set; }

        [JsonProperty("errmsg")]
        public string ErrMsg { get; set; }
    }

.NET微信網頁開發相關文章教程

https://github.com/YSGStudyHards/DotNetGuide

DotNetGuide技術社群交流群

  • DotNetGuide技術社群是一個面向.NET開發者的開源技術社群,旨在為開發者們提供全面的C#/.NET/.NET Core相關學習資料、技術分享和諮詢、專案推薦、招聘資訊和解決問題的平臺。
  • 在這個社群中,開發者們可以分享自己的技術文章、專案經驗、遇到的疑難技術問題以及解決方案,並且還有機會結識志同道合的開發者。
  • 我們致力於構建一個積極向上、和諧友善的.NET技術交流平臺,為廣大.NET開發者帶來更多的價值和成長機會。

歡迎加入DotNetGuide技術社群微信交流群👪

參考文章

https://developers.weixin.qq.com/doc/offiaccount/User_Management/Get_users_basic_information_UnionID.html

相關文章