微信开发中使用通用函数处理,以重定向的方式实现用户身份信息的获取并转回原来页面
在开发微信应用的时候,我们往往需要确认用户的身份,一般公众号唯一区别用户的身份是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页面里面处理用户身份信息的利器,希望对大家在开发微信公众号或者企业微信,获取用户身份的时候,提供好的参考思路和代码。
转载请注明出处:撰写人:伍华聪 http://www.iqidi.com