1. 程式人生 > >微信開發中使用通用函式處理,以重定向的方式實現使用者身份資訊的獲取並轉回原來頁面

微信開發中使用通用函式處理,以重定向的方式實現使用者身份資訊的獲取並轉回原來頁面

在開發微信應用的時候,我們往往需要確認使用者的身份,一般公眾號唯一區別使用者的身份是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頁面裡面處理使用者身份資訊的利器,希望對大家在開發微信公眾號或者企業微信,獲取使用者身份的時候,提供好的參考思路和程式碼。

&n