Every day is wonderful

分享与创新 并大胆的去尝试新鲜事物。。。。

ASP.NET 微信授权OPENID的四步走

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:00
using 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 = “”;
        //用户id
        public 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 = “”;
        #endregion
        protected void Page_Load(object sender, EventArgs e)
        {
            /*
            *微信认证获取openid部分:
            *临时认证code
            */
            //微信认证部分:第二步 获得code
            string code = Request[“code”];
            if (string.IsNullOrEmpty(code))
            {
                //如果code没获取成功,重新拉取一遍
                OpenAccess();
            }
            //微信认证部分:第三步 获得openid
            string 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(); //头像url
            province = outputObj1[“province”].ToString(); ;
            country = outputObj1[“country”].ToString(); ;
            language = outputObj1[“language”].ToString(); ;
            city = outputObj1[“city”].ToString(); ;
            //将获得的用户信息填入到session中
            Session[“openid”] = outputObj1[“openid”];
            //转向回入口
            //OpenAccess();
        }
        //获取code
        private 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
            {
                //跳转到前端页面.aspx
                Response.Redirect(Request.Url.ToString());
            }
        }
    }
}
二〇一七年四月二十三日
小才
点赞

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注