ASP.NET 微信授权OPENID的四步走
腾讯官方文件介绍真不怎么样!折腾了蛮久的!
基本原理为
基本原理为
Scope建议为snsapi_userinfo
{1、以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)2、以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。}1.通过POST微信官方的URL获取CODE并post到跳转的URL!https://open.weixin.qq.com/connect/oauth2/authorize?appid=【此处为APPID】&redirect_uri=【此处为经过URLEncode处理的URLhttp%3a%2f%2f*******.340500.com%2fitems%2freg.aspx】&response_type=code&scope=【两种认证方式分别为snsapi_base和snsapi_userinfo】&state=STATE#wechat_redirect
2. 通过获取到的code换取access_token
https://api.weixin.qq.com/sns/oauth2/access_token?appid=【此处为APPID】&secret=【此处为SECRET】&code=【此处为第一步获取的CODE】&grant_type=authorization_code
3. 可以刷新access_token(用于7200s的加时授权)(7天、30天、60天、90天)
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=【此处为APPID】&grant_type=【此处为第二步获取的refresh_token值】&refresh_token=REFRESH_TOKEN
4.拉去用户的信息(第一步的scope模式为snsapi_userinfo)
https://api.weixin.qq.com/sns/userinfo?access_token=【此处为第二步获取的access_token】&openid=【此处为第二步获取的OPENID】&lang=zh_CN核心代码如下:首先需要通过NUGET安装 http的引用包【Microsoft HTTP Client libraries】 并引用using System.Net.Http; 与using System.Net.Http.Headers;!对JSON序列化与反序列化需要引用 Newtonsoft.Json!
HttpClientHelper.cs类文件:using System;using System.Collections.Generic;using System.Web;using System.Net;using Newtonsoft.Json;using Newtonsoft.Json.Linq;
using System.Net.Http;using System.Net.Http.Headers;using System.Xml.Serialization;using System.IO;using System.Threading.Tasks;namespace WxPayAPI.business{public class HttpClientHelper{/// <summary>/// get请求/// </summary>/// <param name=”url”></param>/// <returns></returns>public static string GetResponse(string url){if (url.StartsWith(“https”)){ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;}var httpClient = new HttpClient();httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(“application/json”));HttpResponseMessage response = httpClient.GetAsync(url).Result;if (response.IsSuccessStatusCode){string result = response.Content.ReadAsStringAsync().Result;return result;}return null;}public static T GetResponse<T>(string url)where T : class, new(){if (url.StartsWith(“https”))ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;var httpClient = new HttpClient();httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(“application/json”));HttpResponseMessage response = httpClient.GetAsync(url).Result;T result = default(T);if (response.IsSuccessStatusCode){Task<string> t = response.Content.ReadAsStringAsync();string s = t.Result;result = JsonConvert.DeserializeObject<T>(s);}return result;}/// <summary>/// post请求/// </summary>/// <param name=”url”></param>/// <param name=”postData”>post数据</param>/// <returns></returns>public static string PostResponse(string url, string postData){if (url.StartsWith(“https”))ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;HttpContent httpContent = new StringContent(postData);httpContent.Headers.ContentType = new MediaTypeHeaderValue(“application/json”);var httpClient = new HttpClient();HttpResponseMessage response = httpClient.PostAsync(url, httpContent).Result;if (response.IsSuccessStatusCode){string result = response.Content.ReadAsStringAsync().Result;return result;}return null;}/// <summary>/// 发起post请求/// </summary>/// <typeparam name=”T”></typeparam>/// <param name=”url”>url</param>/// <param name=”postData”>post数据</param>/// <returns></returns>public static T PostResponse<T>(string url, string postData)where T : class, new(){if (url.StartsWith(“https”))ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;HttpContent httpContent = new StringContent(postData);httpContent.Headers.ContentType = new MediaTypeHeaderValue(“application/json”);var httpClient = new HttpClient();T result = default(T);HttpResponseMessage response = httpClient.PostAsync(url, httpContent).Result;if (response.IsSuccessStatusCode){Task<string> t = response.Content.ReadAsStringAsync();string s = t.Result;result = JsonConvert.DeserializeObject<T>(s);}return result;}/// <summary>/// V3接口全部为Xml形式,故有此方法/// </summary>/// <typeparam name=”T”></typeparam>/// <param name=”url”></param>/// <param name=”xmlString”></param>/// <returns></returns>public static T PostXmlResponse<T>(string url, string xmlString)where T : class, new(){if (url.StartsWith(“https”))ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;HttpContent httpContent = new StringContent(xmlString);httpContent.Headers.ContentType = new MediaTypeHeaderValue(“application/json”);var httpClient = new HttpClient();T result = default(T);HttpResponseMessage response = httpClient.PostAsync(url, httpContent).Result;if (response.IsSuccessStatusCode){Task<string> t = response.Content.ReadAsStringAsync();string s = t.Result;result = XmlDeserialize<T>(s);}return result;}/// <summary>/// 反序列化Xml/// </summary>/// <typeparam name=”T”></typeparam>/// <param name=”xmlString”></param>/// <returns></returns>public static T XmlDeserialize<T>(string xmlString)where T : class, new(){try{var ser = new XmlSerializer(typeof(T));using (var reader = new StringReader(xmlString)){return (T)ser.Deserialize(reader);}}catch (Exception ex){throw new Exception(“XmlDeserialize发生异常:xmlString:” + xmlString + “异常信息:” + ex.Message);}}}}
=======================================================================================================.cs后端文件
using System;using System.Collections.Generic;using System.Data.SqlClient;using System.Configuration;using System.Text;using System.Data;using System.IO;using System.Net;using Newtonsoft.Json;using Newtonsoft.Json.Linq; //JSON序列化与反序列 2017年4月23日 14:45:00using System.Web;using System.Web.UI;using System.Web.UI.WebControls;namespace WxPayAPI.items{public partial class signup : System.Web.UI.Page{public string code = “”;public string access_token = “”;//用户idpublic string openid = “”;//公众号信息部分public string appid = ConfigurationManager.AppSettings[“AppId”];public string appsecret = ConfigurationManager.AppSettings[“AppSecret”];public string redirect_uri = HttpUtility.UrlEncode(“http://XXXXXXX.340500.com/items/signup.aspx“);public string scope = “snsapi_userinfo”;#region 显示页面public string accesstoken;public string nickname;public string sex;public string headimgurl;public string province;public string country;public string language;public string city;public string privilege = “”;#endregionprotected void Page_Load(object sender, EventArgs e){/**微信认证获取openid部分:*临时认证code*///微信认证部分:第二步 获得codestring code = Request[“code”];if (string.IsNullOrEmpty(code)){//如果code没获取成功,重新拉取一遍OpenAccess();}//微信认证部分:第三步 获得openidstring url = string.Format(“https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code”, appid, appsecret, code);string result = business.HttpClientHelper.GetResponse(url);//business.LogHelper.WriteLog(result);JObject outputObj = JObject.Parse(result);//微信认证部分:第四步 获得更多信息accesstoken = outputObj[“access_token”].ToString();openid = outputObj[“openid”].ToString();url = string.Format(“https://api.weixin.qq.com/sns/userinfo?access_token={0}&openid={1}&lang=zh_CN”, accesstoken, openid);string result1 = business.HttpClientHelper.GetResponse(url);//business.LogHelper.WriteLog(result1);JObject outputObj1 = JObject.Parse(result1);//将json转为数组//以下是第四步获得的信息:nickname = outputObj1[“nickname”].ToString(); //昵称sex = outputObj1[“sex”].ToString(); //性别什么的headimgurl = outputObj1[“headimgurl”].ToString(); //头像urlprovince = outputObj1[“province”].ToString(); ;country = outputObj1[“country”].ToString(); ;language = outputObj1[“language”].ToString(); ;city = outputObj1[“city”].ToString(); ;//将获得的用户信息填入到session中Session[“openid”] = outputObj1[“openid”];//转向回入口//OpenAccess();}//获取codeprivate void getcode(){code = Request[“code”];if (string.IsNullOrEmpty(code)){//如果code没获取成功,重新拉取一遍OpenAccess();}}public void OpenAccess(){//判断session不存在if (Session[“openid”] == null){//认证第一步:重定向跳转至认证网址string url = string.Format(“https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&&response_type=code&scope=snsapi_userinfo&m=oauth2#wechat_redirect”, appid, redirect_uri);Response.Redirect(url);}//判断session存在else{//跳转到前端页面.aspxResponse.Redirect(Request.Url.ToString());}}}}
二〇一七年四月二十三日
小才
小才