在開發微信應用的時候,我們往往需要確認用戶的身份,一般公眾號唯一區別用戶的身份是openid資訊,但是這個資訊并不是可以直接獲取到,需要通過code進行獲取,而code的獲取則需要用戶進行一個授權的處理才能獲得,本篇隨筆通過結合Session的方式,自動判斷用戶狀態,如果用戶首次訪問頁面,則以重定向的方式實作用戶身份資訊的獲取并轉回原來頁面,
1、常規的頁面身份獲取處理
之前為了在某個頁面里面獲取用戶身份資訊,需要把URL進行一個授權的處理URL,如下所示,

通過這樣的方式處理,我們可以在頁面處理里面,獲得code引數,然后根據code引數獲取openid,
string code = Request.QueryString["code"];
var result = baseApi.GetAuthToken(accountInfo.AppID, accountInfo.AppSecret, code);if (result != null && !string.IsNullOrEmpty(result.openid)){ Session["openid"] = result.openid;//存盤在Session}
其中 GetAuthToken 是我們根據微信API進行封裝的一個通過code換取網頁授權access_token的介面方法,
/// <summary> /// 通過code換取網頁授權access_token /// 首先請注意,這里通過code換取的是一個特殊的網頁授權access_token,與基礎支持中的access_token(該access_token用于呼叫其他介面)不同, /// 公眾號可通過下述介面來獲取網頁授權access_token, /// 如果網頁授權的作用域為snsapi_base,則本步驟中獲取到網頁授權access_token的同時,也獲取到了openid,snsapi_base式的網頁授權流程即到此為止, /// </summary> /// <param name="appId">公眾號的唯一標識</param> /// <param name="appSecret">公眾號的appsecret</param> /// <param name="code">code作為換取access_token的票據,每次用戶授權帶上的code將不一樣,code只能使用一次,5分鐘未被使用自動過期,</param> /// <param name="grantType">填寫為authorization_code</param> /// <returns></returns> public AccessTokenResult GetAuthToken(string appId, string appSecret, string code, string grantType = "authorization_code") { var key = code + "_AuthToken"; AccessTokenResult itemResult = MemoryCacheHelper.GetItem<AccessTokenResult>(key); if (itemResult == null) { var url = string.Format("https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type={3}", appId, appSecret, code, grantType); var authToken = WeJsonHelper<AccessTokenResult>.ConvertJson(url); MemoryCacheHelper.AddItem(key, authToken);//先加入一個獲取的值 } //然后每次從其中取,如果超過時間則啟用重繪機制 var access_token = MemoryCacheHelper.GetCacheItem<AccessTokenResult>(key, delegate() { return RefreshAuthToken(appId, itemResult.access_token); }, new TimeSpan(0, 0, 7000)//7000秒過期 ); return access_token; }
這種方式能夠正常獲取openid,不過每個選單這樣進行URL處理,并且每次重復這樣的邏輯獲取openid,肯定不是什么好的辦法,
因此考慮一種通用的方式來處理,以減少這些曲折處理程序,
2、通用函式處理,以重定向的方式實作用戶身份資訊
上面提出了,采用常規處理方式,選單URL需要先轉移,后臺重復處理code的轉換,非常不方便我們開發業務功能,
其實我們可以把以上獲取用戶身份的處理放置在一個通用函式里面,這樣每次確保獲得Openid即可,如果第一次訪問頁面,那么記錄當前頁面地址,并重定向到獲取code的頁面,并決議code為openid即可,然后放在Session里面存盤起來,下次直接讀取Session獲取即可,

我們首先在入口頁面里面記錄當前頁面地址,然后轉去判斷并獲取openid即可,
如果在session里面沒有獲取到Openid,那么認為是第一訪問頁面,重新判斷是否有code進來,如果沒有,先獲取code,然后轉回到當前的 AuthOpenId 地址入口來,
/// <summary>/// 通過重新轉向,獲取用戶code并轉換為openid,/// 用于自動獲取當前用戶的身份,/// </summary>/// <returns></returns>protected ActionResult AuthOpenId(){ //先判斷Session是否存在 var open_id = Session["openid"]; if (open_id == null) { //如果第一次(沒有code),則再次轉到授權頁面重新獲取code string code = Request.QueryString["code"]; if (string.IsNullOrEmpty(code)) { var authUrl = baseApi.GetAuthorizeUrl(accountInfo.AppID, Request.Url.AbsoluteUri, "", OAuthScope.snsapi_base); Response.Redirect(authUrl); return null; }
如果是已經獲取到了code,則根據code進行決議獲取openid,如下代碼所示,
else { //如果成功獲取code,那么根據code獲取openid var result = baseApi.GetAuthToken(accountInfo.AppID, accountInfo.AppSecret, code); if (result != null && !string.IsNullOrEmpty(result.openid)) { //LogHelper.Info("openid:" + result.openid); Session["openid"] = result.openid;//存盤在Session } }
最后如果順利獲得openid,那么回傳到最初入口的頁面地址(已經存放地址在Session里面了)
//獲取回傳的連接 var backUrl = Session["back_url"]; if (backUrl != null) { return Redirect(backUrl.ToString()); } else { return View("PersonalInfo");//回傳個人頁面 }
整個函式的完整的代碼如下所示,
/// <summary>/// 通過重新轉向,獲取用戶code并轉換為openid,/// 用于自動獲取當前用戶的身份,/// </summary>/// <returns></returns>protected ActionResult AuthOpenId(){ //先判斷Session是否存在 var open_id = Session["openid"]; if (open_id == null) { //如果第一次(沒有code),則再次轉到授權頁面重新獲取code string code = Request.QueryString["code"]; if (string.IsNullOrEmpty(code)) { var authUrl = baseApi.GetAuthorizeUrl(accountInfo.AppID, Request.Url.AbsoluteUri, "", OAuthScope.snsapi_base); Response.Redirect(authUrl); return null; } else { //如果成功獲取code,那么根據code獲取openid var result = baseApi.GetAuthToken(accountInfo.AppID, accountInfo.AppSecret, code); if (result != null && !string.IsNullOrEmpty(result.openid)) { Session["openid"] = result.openid;//存盤在Session } } } //獲取回傳的連接 var backUrl = Session["back_url"]; if (backUrl != null) { return Redirect(backUrl.ToString()); } else { return View("PersonalInfo");//回傳個人頁面 }}
這樣我們在選單里面,就不需要前面所說的轉義函式處理了,所有的身份獲取都通過標準操作確保獲取用戶的openid了,

頁面的處理也變得相對容易一些,根據用戶身份顯示不同的視圖頁面,
/// <summary>/// 患者問診/// </summary>/// <returns></returns>public ActionResult DrugInquiry(){ Session["back_url"] = Request.Url.AbsoluteUri; AuthOpenId();//自動獲取當前用戶的身份, string openid = (string)Session["openid"]; if (!string.IsNullOrEmpty(openid)) { //重繪配置JS的引數 RefreshTicket(); ViewBag.openid = openid; var userInfo = BLLFactory<User>.Instance.FindByOpenId(openid); if (userInfo != null) { //識別用戶身份后的處理邏輯 ............... } return View("DrugInquiry"); } else { ViewBag.Title = "無法獲取用戶身份資訊"; ViewBag.Message = "無法獲取用戶身份資訊"; ViewBag.Type = "error"; return View("info"); }}
以上就是微信開發中使用通用函式處理,以重定向的方式實作用戶身份資訊的獲取并轉回原來頁面的做法,這個函式給我們減輕了很多繁瑣的問題,并且減少了重復復制代碼來獲取用戶身份的弊端,是我們在H5頁面里面處理用戶身份資訊的利器,希望對大家在開發微信公眾號或者企業微信,獲取用戶身份的時候,提供好的參考思路和代碼,
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/8098.html
標籤:ASP.NET
