微信开发中使用通用函数处理,以重定向的方式实现用户身份信息的获取并转回原来页面

在开发微信应用的时候,我们往往需要确认用户的身份,一般公众号唯一区别用户的身份是openid信息,但是这个信息并不是可以直接获取到,需要通过code进行获取,而code的获取则需要用户进行一个授权的处理才能获得,本篇随笔通过结合Session的方式,自动判断用户状态,如果用户首次访问页面,则以重定向的方式实现用户身份信息的获取并转回原来页面。

1、常规的页面身份获取处理

之前为了在某个页面里面获取用户身份信息,需要把URL进行一个授权的处理URL,如下所示。

image

通过这样的方式处理,我们可以在页面处理里面,获得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获取即可。

image

我们首先在入口页面里面记录当前页面地址,然后转去判断并获取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了。

image

页面的处理也变得相对容易一些,根据用户身份显示不同的视图页面。

/// <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页面里面处理用户身份信息的利器,希望对大家在开发微信公众号或者企业微信,获取用户身份的时候,提供好的参考思路和代码。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271