功能:认证服务号通过网页授权获取用户信息
--公众号后台配置
》此次设置的是网页授权域名,设置成你调试的域名或者正式备案的域名(不带http或https)。
--自定义菜单设置
设置参数:
appid:微信公众号的appid
uri:微信网页授权后跳转的网页(该uri需经过UrlEncode编码)
scope:此处使用 snsapi_userinfo方式
关于网页授权的两种scope的区别说明
1、以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)
2、以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。
--授权步骤
1 第一步:用户同意授权,获取code
2 第二步:通过code换取网页授权access_token
3 第三步:刷新access_token(如果需要)
4 第四步:拉取用户信息(需scope为 snsapi_userinfo)
--后台代码
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Xml;namespace wxweb.Areas.wechatPage.Controllers {public class service_PersonalController : Controller{// GET: wechatPage/service_Personalpublic ActionResult Index(){//--------------微信oauth授权---------------wxPlatForm.OAuth.wechatOAuth oauth = new wxPlatForm.OAuth.wechatOAuth();oauth.appid = appid;//微信公众号的appidoauth.secret = secret;//微信公众号的AppSecretoauth.get_code();//获取token及userinfo信息if (oauth.o_user != null){//获取用户信息成功,继续逻辑业务操作 }else{return RedirectToAction("Error", "service_Personal");}//--------------end微信oauth授权---------------return View();}} }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web; using System.Web.Script.Serialization;namespace wxPlatForm.OAuth {public class wechatOAuth{////// 公众号的唯一标识 /// public string appid;/// /// 公众号的appsecret /// public string secret;public OAuthAccess_Token o_token;public OAuthUser o_user;private string code;/// /// 获取code/// public void get_code() {try{code = HttpContext.Current.Request.QueryString["Code"];if (code != ""&&code!=null) {get_access_token();}}catch (Exception ex){common.CommonMethod.WriteTxt(ex.Message);}}/// /// 通过code换取网页授权access_token/// public void get_access_token() {Dictionary<string, string> obj = new Dictionary<string, string>();var client = new System.Net.WebClient();var serializer = new JavaScriptSerializer();string url = string.Format("https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code", appid, secret, code);client.Encoding = System.Text.Encoding.UTF8;string dataaccess = "";try{dataaccess = client.DownloadString(url);//获取字典obj = serializer.Deserialize string, string>>(dataaccess);string accessToken = "";if (obj.TryGetValue("access_token", out accessToken)) //判断access_Token是否存在 {o_token =new OAuthAccess_Token {access_token=obj["access_token"],expires_in =Convert.ToInt32( obj["expires_in"]),refresh_token = obj["refresh_token"],openid = obj["openid"],scope = obj["scope"]};if (o_token.scope == "snsapi_userinfo") {get_userinfo(o_token.access_token, o_token.openid);}}else //access_Token 失效时重新发送。 {//存log方法common.CommonMethod.WriteTxt("access_token 获取失败,time:"+DateTime.Now.ToLongTimeString());}}catch (Exception e){//存log方法 common.CommonMethod.WriteTxt(e.Message);}}/// /// 拉取用户信息(需scope为 snsapi_userinfo)/// /// 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同/// 用户的唯一标识public void get_userinfo(string access_token,string openid) {Dictionary<string, object> obj = new Dictionary<string, object>();var client = new System.Net.WebClient();JavaScriptSerializer serializer = new JavaScriptSerializer();string url = string.Format("https://api.weixin.qq.com/sns/userinfo?access_token={0}&openid={1}&lang=zh_CN", access_token, openid);client.Encoding = System.Text.Encoding.UTF8;string dataaccess = "";try{dataaccess = client.DownloadString(url);obj = serializer.Deserialize string, object>>(dataaccess);object user_openid = "";if (obj.TryGetValue("openid", out user_openid)) //判断access_Token是否存在 {o_user = new OAuthUser{openid = obj["openid"].ToString(),nickname = obj["nickname"].ToString(),sex =Convert.ToInt32( obj["sex"]),province = obj["province"].ToString(),city = obj["city"].ToString(),country = obj["country"].ToString(),headimgurl = obj["headimgurl"].ToString(),privilege =obj["privilege"].ToString(),unionid =""};}else //access_Token 失效时重新发送。 {//存log方法common.CommonMethod.WriteTxt("用户信息 获取失败,time:" + DateTime.Now.ToLongTimeString());}}catch (Exception e){//存log方法 common.CommonMethod.WriteTxt(e.Message);}}/// /// 检验授权凭证(access_token)是否有效/// /// 公众号的唯一标识 /// 填写通过access_token获取到的refresh_token参数public void refresh_access_token(string refresh_token) {Dictionary<string, string> obj = new Dictionary<string, string>();var client = new System.Net.WebClient();var serializer = new JavaScriptSerializer();string url = string.Format("https://api.weixin.qq.com/sns/oauth2/refresh_token?appid={0}&grant_type=refresh_token&refresh_token={1}", this.appid, refresh_token);client.Encoding = System.Text.Encoding.UTF8;string dataaccess = "";try{dataaccess = client.DownloadString(url);//获取字典obj = serializer.Deserialize string, string>>(dataaccess);string accessToken = "";if (obj.TryGetValue("access_token", out accessToken)) //判断access_Token是否存在 {OAuthAccess_Token o_token = new OAuthAccess_Token{access_token = obj["access_token"],expires_in = Convert.ToInt32(obj["expires_in"]),refresh_token = obj["refresh_token"],openid = obj["openid"],scope = obj["scope"]};if (o_token.scope == "snsapi_userinfo"){get_userinfo(o_token.access_token, o_token.openid);}}else //access_Token 失效时重新发送。 {//存log方法common.CommonMethod.WriteTxt("access_token 获取失败,time:" + DateTime.Now.ToLongTimeString());}}catch (Exception e){//存log方法 common.CommonMethod.WriteTxt(e.Message);}}/// /// 刷新access_token(如果需要)/// public void check_access_token(){}} }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace wxPlatForm.OAuth {public class OAuthAccess_Token{public string access_token { get; set; }public int expires_in { get; set; }public string refresh_token { get; set; }////// 用户针对当前公众号的唯一标识 /// 关注后会产生,返回公众号下页面也会产生 /// public string openid { get; set; }public string scope { get; set; }/// /// 当前用户的unionid,只有在用户将公众号绑定到微信开放平台帐号后 /// public string unionid { get; set; }} }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace wxPlatForm.OAuth {////// 授权之后获取用户基本信息 /// public class OAuthUser{public string openid { get; set; }public string nickname { get; set; }public int sex { get; set; }public string province { get; set; }public string city { get; set; }public string country { get; set; }public string headimgurl { get; set; }/// /// 用户特权信息,json 数组 /// //public JArray privilege { get; set; }public string privilege { get; set; }public string unionid { get; set; }} }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.IO; using System.Web; using System.Web.Script.Serialization;namespace common {////// 通用方法类/// public class CommonMethod{#region 记录bug,以便调试/// /// 记录bug,以便调试/// public static bool WriteTxt(string str){try{string LogPath = HttpContext.Current.Server.MapPath("/err_log/");if (!Directory.Exists(LogPath)){Directory.CreateDirectory(LogPath);}FileStream FileStream = new FileStream(System.Web.HttpContext.Current.Server.MapPath("/err_log//xiejun_" + DateTime.Now.ToLongDateString() + "_.txt"), FileMode.Append);StreamWriter StreamWriter = new StreamWriter(FileStream);//开始写入 StreamWriter.WriteLine(str);//清空缓冲区 StreamWriter.Flush();//关闭流 StreamWriter.Close();FileStream.Close();}catch (Exception){return false;}return true;}#endregion} }