微信公众号开发之网页授权获取用户基本信息

前言

如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑。

微信公众号开发之网页授权获取用户基本信息

注意:网页授权两种方式

微信公众号开发之网页授权获取用户基本信息

更多网页授权请查阅官网文档:网页授权

静默授权

静默授权即可以在用户关注的的时候,获取用户基本信息,此过程用户无感知。

第一步,通过工厂类 转发请求

      
 /// <returns></returns>
 public string HandleRequest()
 {
 string response = string.Empty;
 EventMessage em = EventMessage.LoadFromXml(RequestXml);
 if (em != null)
 {
 switch (em.Event.ToLower())
 {
 case ("subscribe"):
 response = SubscribeEventHandler(em);//通过工厂类分发过来的请求,匹配到关注事件
 break;
 case ("unsubscribe"):
 response = Un_SubscribeEventHandler(em);
 break;
 case "click":
 response = ClickEventHandler(em);
 break;
 }
 }
 return response;
 }

第二步,写用户关注事件

     /// <summary>
 /// 用户关注
 /// </summary>
 /// <param name="em"></param>
 /// <returns></returns>
 public string SubscribeEventHandler(EventMessage em)
 {
 //回复欢迎消息
 WeChat.Messages.TextMessage tm = new WeChat.Messages.TextMessage();
 tm.ToUserName = em.FromUserName;//OpenId
 tm.FromUserName = em.ToUserName;//公众号原始Id
 tm.CreateTime = Common.GetNowTime();
 tm.Content = "欢迎您关注****,我是服务小二,有事就问我~

";
 tm.GenerateContent();
 //如有业务需要,可在此处先判断该用户是否已关注
       //此处得到OpenId
       show.ShowUserInfo(em.FromUserName,em.ToUserName);
       return tm.GenerateContent();
 }

第三步,根据得到的OpenId及accesstoken,即可获取用户基本信息(此处演示是将该用户存入数据库中)

   /// <summary>
 /// 根据OpenId将此条粉丝记录插入数据库中
 /// </summary>
 /// <param name="FromUserName"></param>
 /// <param name="ToUserName"></param>
 public void ShowUserInfo(string FromUserName, string ToUserName)
 {
 try
 {
 Models.Users user = new Models.Users();
 DAL.User userInfo = new DAL.User();
 //获取accesstoken,获取用户基本信息需要Openid和accesstoken即可
         accesstoken = Utility.Context.AccessToken;
         string url = string.Format("https://api.weixin.qq.com/cgi-bin/user/info?access_token={0}&openid={1}&lang=zh_CN", accesstoken, FromUserName);
 string result = HttpUtility.GetData(url);
 XDocument doc = XmlUtility.ParseJson(result, "root");
 XElement root = doc.Root;
 if (root != null)
 {
 #region 取值/存值
 
 subscribe = root.Element("subscribe").Value;//是否关注 1 是关注 
 nickname = root.Element("nickname").Value; //昵称
 sex = root.Element("sex").Value; //性别什么
 headimgurl = root.Element("headimgurl").Value; //头像url
 province = root.Element("province").Value;//地区 
 country = root.Element("country").Value;
 language = root.Element("language").Value;
 subscribe_time = root.Element("subscribe_time").Value;
 DateTime create_time = Common.GetTime(subscribe_time);//将时间戳转换为当前时间
 city = root.Element("city").Value;
 user.OpenID = FromUserName;//OpenID即粉丝ID
 user.PublicId = ToUserName;
 user.UserID = FromUserName;
 user.NickName = nickname;
 user.Sex = int.Parse(sex);
 user.Subscribe = int.Parse(subscribe);
 user.Country = country;
 user.Province = province;
 user.City = city;
 user.CreateDate = create_time;
 user.HeadimgUrl = headimgurl;
 //将user实体存入数据库中
 bool show = _user.Add(user);
 #endregion
 }
 }
 catch
 {
 throw (new ArgumentNullException());
 }
 }

上面代码中 AccessToken的实现,新建一个Context类即可

private static DateTime GetAccessToken_Time;
 /// <summary>
 /// 过期时间为7200秒
 /// </summary>
 private static int Expires_Period = 7200;
 /// <summary>
 /// 
 /// </summary>
 private static string mAccessToken;
 public static string AppID = "换成相应公众号的即可";
 public static string AppSecret = "换成相应公众号的即可";
 /// <summary>
 /// 调用获取ACCESS_TOKEN,包含判断是否过期
 /// </summary>
 public static string AccessToken
 {
 get
 {
 //如果为空,或者过期,需要重新获取
 if (string.IsNullOrEmpty(mAccessToken) || HasExpired())
 {
 //获取access_token
 mAccessToken = GetAccessToken(AppID, AppSecret);
 }
 return mAccessToken;
 }
 }
 /// <summary>
 /// 获取ACCESS_TOKEN方法
 /// </summary>
 /// <param name="appId"></param>
 /// <param name="appSecret"></param>
 /// <returns></returns>
 private static string GetAccessToken(string appId, string appSecret)
 {
 string url = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", appId, appSecret);
 string result = HttpUtility.GetData(url);
 XDocument doc = XmlUtility.ParseJson(result, "root");
 XElement root = doc.Root;
 if (root != null)
 {
 XElement access_token = root.Element("access_token");
 if (access_token != null)
 {
 GetAccessToken_Time = DateTime.Now;
 if (root.Element("expires_in") != null)
 {
 Expires_Period = int.Parse(root.Element("expires_in").Value);
 }
 return access_token.Value;
 }
 else
 {
 GetAccessToken_Time = DateTime.MinValue;
 }
 }
 return null;
 }
 /// <summary>
 /// 判断Access_token是否过期
 /// </summary>
 /// <returns>bool</returns>
 private static bool HasExpired()
 {
 if (GetAccessToken_Time != null)
 {
 //过期时间,允许有一定的误差,一分钟。获取时间消耗
 if (DateTime.Now > GetAccessToken_Time.AddSeconds(Expires_Period).AddSeconds(-60))
 {
 return true;
 }
 }
 return false;
 }
GetData的实现
     public static string GetData(string url)
 {
 return SendGetHttpRequest(url, "application/x-www-form-urlencoded");
 }
ParseJson的实现
     public static XDocument ParseJson(string json, string rootName)
 {
 return JsonConvert.DeserializeXNode(json, rootName);
 }

关于第三步的 HttpUtility类中还有一些其他公用帮助方法,在这里一并放出,调用即可

微信公众号开发之网页授权获取用户基本信息

View Code

顺便提下上文中用到的User类如下

public class Users
 {
 /// <summary>
 /// 全局凭证唯一Id
 /// </summary>
 public string OpenID { get; set; }
 /// <summary>
 /// 公众号Id
 /// </summary>
 public string PublicId { get; set; }
 /// <summary>
 /// 用户Id
 /// </summary>
 public string UserID { get; set; }
 /// <summary>
 /// 昵称
 /// </summary>
 public string NickName { get; set; }
 /// <summary>
 /// 性别 1是男 0是女
 /// </summary>
 public int Sex { get; set; }
 /// <summary>
 /// 是否关注 1是关注 
 /// </summary>
 public int Subscribe { get; set; }
 /// <summary>
 /// 国家
 /// </summary>
 public string Country { get; set; }
 /// <summary>
 /// 地区
 /// </summary>
 public string Province { get; set; }
 /// <summary>
 /// 城市
 /// </summary>
 public string City { get; set; }
 /// <summary>
 /// 关注时间
 /// </summary>
 public DateTime CreateDate { get; set; }
 /// <summary>
 /// 用户头像
 /// </summary>
 public string HeadimgUrl { get; set; }
 /// <summary>
 /// 第三方平台Id,可为空
 /// </summary>
 public string UnionID { get; set; }
 /// <summary>
 /// 用户取消关注时间
 /// </summary>
 public DateTime Un_Subscribe_Time { get; set; }
 }

演示效果

数据库中此时是存在10条数据的,当点击关注此公众号的时候,就将此用户的基本信息存入数据库了,数据库刷新后变成11条数据

微信公众号开发之网页授权获取用户基本信息

微信公众号开发之网页授权获取用户基本信息

网页授权流程

微信公众号开发之网页授权获取用户基本信息

具体介绍依然可参考官网文档:网页授权

第一步,判断该用户是否获取授权,若没有授权,则跳转至授权页面,若授权,则获取基本信息

核心代码

/// <summary>
 /// 获取授权用户的基本信息,包括头像,姓名,等等(推荐方法)
 /// </summary>
 /// <param name="accessToken">用户授权之后的accessToken</param>
 /// <param name="openid">用户授权之后的openid</param>
 /// <returns></returns>
 public static ShouQuanWeiXinUserInfo GetShouQuanMessage()
 {
 //先判断是否有获取到用户授权的Code,HttpContext.Current.Session["ShouquanCode"]
 if (HttpContext.Current.Session["ShouquanCode"] == null|| HttpContext.Current.Session["ShouquanCode"].ToString()=="")
 {
 HttpContext.Current.Session["ShouquanCode"] = "123";
 //用户授权的Code
 GetShouQuanCodeUrl(HttpContext.Current.Request.Url.AbsoluteUri);
 }
 else if(HttpContext.Current.Request.QueryString["code"] == null || HttpContext.Current.Request.QueryString["code"] == "")
 {
 //用户授权的Code
 GetShouQuanCodeUrl(HttpContext.Current.Request.Url.AbsoluteUri);
 }
 else
 {
 var model = ShouQuanAccessToken(HttpContext.Current.Request.QueryString["code"]);
 var url =
 $"https://api.weixin.qq.com/sns/userinfo?access_token={model.access_token}&openid={model.openid}&lang=zh_CN";
 string gethtml = MyHttpHelper.HttpGet(url);
 var ac = JsonHelpers.ToObject<ShouQuanWeiXinUserInfo>(gethtml);
 return ac;
 }
 return null;
 }

其中,用户授权的code方法如下:

/// <summary>
 /// 重新获取用户授权的Code,可以获取用户的基本信息(头像,姓名,等等)(推荐用的方法)
 /// </summary>
 /// <param name="url">目标Url</param>
 /// <returns></returns>
 public static void GetShouQuanCodeUrl(string url)
 {
 string CodeUrl = "";
 //加密过的url
 string value = HttpUtility.UrlEncode(url);
 //用户授权后的Code
 CodeUrl = $"https://open.weixin.qq.com/connect/oauth2/authorize?appid={Appid}&redirect_uri={value}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
 System.Web.HttpContext.Current.Response.Redirect(CodeUrl);//先跳转到微信的服务器,取得code后会跳回来这页面的
 }

其中ShouQuanAccessToken方法

/// <summary>
 //用户授权之后,获取授权的Access_Token与基本的Access_Token是不同的(推荐方法)
 /// </summary>
 /// <param name="code">用户授权之后的Code</param>
 /// <returns></returns>
 public static OauthAccessToken ShouQuanAccessToken(string code)
 {
 var url = $"https://api.weixin.qq.com/sns/oauth2/access_token?appid={Appid}&secret={Secret}&code={code}&grant_type=authorization_code";
 string gethtml = MyHttpHelper.HttpGet(url);
 OauthAccessToken ac = new OauthAccessToken();
 ac = JsonHelpers.ToObject<OauthAccessToken>(gethtml);
 return ac;
 }

用户实体

public class OauthAccessToken
 {
 public string access_token { get; set; }
 public string expires_in { get; set; }
 public string refresh_token { get; set; }
 public string openid { get; set; }
 public string scope { get; set; }
 }

其中用到的MyHttpHelper公众类如下

微信公众号开发之网页授权获取用户基本信息

View Code

封装的JsonHelpers类如下

微信公众号开发之网页授权获取用户基本信息

View Code

其中,如果是VS2015以下的,可以将url字符串改成string.format("")方式

调用取值的方式

微信公众号开发之网页授权获取用户基本信息

效果展示

点击公众号链接效果如下:

微信公众号开发之网页授权获取用户基本信息

未完待续,持续填坑中。。。

__EOF__

原作 者潇十一郎

版权所有:原作者

出 处:http://www.cnblogs.com/zhangxiaoyong/p/6270768.html

相关推荐