微信授权步骤与详解 -- c#篇
注:这里不涉及界面操作,只介绍代码操作。
1.基本原理如下:
从图上所知,第一步用户访问我们的网页,第二步我们后台跳转到微信授权页面,第三步用户点击授权,第四步微信重定向到第三方(我们后台)并且返回code,第五步请求accesstoken获取accesstoken和openid。
2.详细介绍
第一步,用户访问我们网页。
例如,http://test.authorization.com/Main/TA
第二步,我们后台跳转到微信授权页面。(第一次握手)
首先,我们跳转到微信页面,传参数为appid、redirectUrl、response_type、scope、state。
url为:"https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId + "&redirect_uri=" + redirectUrl + "&response_type=code&scope=snsapi_userinfo&state=" + state + "#wechat_redirect"
redirectUrl 为当前后台请求的url。代码如下:
string response_type = "code";// 返回类型,此时固定为:code string scope = "snsapi_userinfo";//应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息) string state = "state";//随便写,微信提供给我们的自定义参数。重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节 string url = string.Format("https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type={2}&scope={3}&state={4}#wechat_redirect",appid, redirect_uri, response_type, scope, state); hconHttpContextBase.Response.Redirect(url, true);//跳转到微信授权
第三步,用户点击授权。
第四步,微信重定向到第三方(我们后台)并且返回code(第二次握手)
微信重定向回我们后台时,会返回code,所以我们可以判断是否有code来确定微信是第几次握手。没code是第一次握手,有code是第二次握手。
第五步,请求accesstoken获取accesstoken和openid
请求代码如下:
string url = "https://api.weixin.qq.com/sns/oauth2/access_token";//请求的url string sUrlpara = "appid=" + appId + "&secret=" + appSecret + "&code=" + code + "&grant_type=authorization_code";//请求的参数 string jsonStr = Toos.HttpGet(url, sUrlpara);//网络get请求 //放回json解析 WeiXinAccessTokenResult result = new WeiXinAccessTokenResult(); if (jsonStr.Contains("errcode")) { WeiXinErrorMsg errorResult = new WeiXinErrorMsg(); errorResult = JsonHelper.ParseFormJson<WeiXinErrorMsg>(jsonStr); result.ErrorResult = errorResult; result.Result = false; } else { WeiXinAccessTokenModel model = new WeiXinAccessTokenModel(); model = JsonHelper.ParseFormJson<WeiXinAccessTokenModel>(jsonStr); result.SuccessResult = model; result.Result = true; }
返回的json是:
//正确的时候: { "access_token":"ACCESS_TOKEN", "expires_in":7200, "refresh_token":"REFRESH_TOKEN", "openid":"OPENID", "scope":"SCOPE", "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" //这里一般没有返回,待定。 } //错误的时候: {"errcode":40029,"errmsg":"invalid code"}
json解析的对象代码
public class WeiXinAccessTokenResult { public WeiXinAccessTokenModel SuccessResult { get; set; } public bool Result { get; set; } public WeiXinErrorMsg ErrorResult { get; set; } } /// <summary> /// 通过code获取access_token 请求成功的实体 /// </summary> public class WeiXinAccessTokenModel { /// <summary> /// 接口调用凭证 /// </summary> public string access_token { get; set; } /// <summary> /// access_token接口调用凭证超时时间,单位(秒) /// </summary> public int expires_in { get; set; } /// <summary> /// 用户刷新access_token /// </summary> public string refresh_token { get; set; } /// <summary> /// 授权用户唯一标识 /// </summary> public string openid { get; set; } /// <summary> /// 用户授权的作用域,使用逗号(,)分隔 /// </summary> public string scope { get; set; } } /// <summary> /// 微信错误访问的情况 /// </summary> public class WeiXinErrorMsg { /// <summary> /// 错误编号 /// </summary> public int errcode { get; set; } /// <summary> /// 错误提示消息 /// </summary> public string errmsg { get; set; } }
Tool.HttpGet方法
public static string HttpGet(string Url, string postDataStr) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr == "" ? "" : "?") + postDataStr); request.Method = "GET"; request.ContentType = "text/html;charset=UTF-8"; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); Stream myResponseStream = response.GetResponseStream(); StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8")); string retString = myStreamReader.ReadToEnd(); myStreamReader.Close(); myResponseStream.Close(); return retString; }
3. 获取用户信息
获取用户很简单,只需要传一个token以及openid获取用户的基本信息。
代码如下:
string url = "https://api.weixin.qq.com/sns/userinfo"; string urlParam = "access_token=" + accessToken + "&openid=" + openId + "⟨=zh_CN"; string jsonStr = Toos.HttpGet(url, urlParam); ; WeiXinUserInfoResult result = new WeiXinUserInfoResult(); result.token = accessToken; if (jsonStr.Contains("errcode")) { WeiXinErrorMsg errorResult = new WeiXinErrorMsg(); errorResult = JsonHelper.ParseFormJson<WeiXinErrorMsg>(jsonStr); result.ErrorMsg = errorResult; result.Result = false; } else { WXUserInfo userInfo = new WXUserInfo(); userInfo = JsonHelper.ParseFormJson<WXUserInfo>(jsonStr); result.UserInfo = userInfo; result.Result = true; }
返回的json对象
{ "openid":" OPENID", " nickname": NICKNAME, "sex":"1", "province":"PROVINCE" "city":"CITY", "country":"COUNTRY", "headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46", "privilege":[ "PRIVILEGE1" "PRIVILEGE2" ], "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" }
解析json对象
public class WeiXinUserInfoResult { public string token { get; set; } /// <summary> /// 微信用户信息 /// </summary> public WXUserInfo UserInfo { get; set; } /// <summary> /// 结果 /// </summary> public bool Result { get; set; } /// <summary> /// 错误信息 /// </summary> public WeiXinErrorMsg ErrorMsg { get; set; } public override string ToString() { return string.Format("UserInfo: {0}, Result: {1}, ErrorMsg: {2}, token:{3}", UserInfo, Result, ErrorMsg, token); } }
备注:
添加jsonhelp类
public class JsonHelper { public JsonHelper() { // // TODO: Add constructor logic here // } /// <summary> /// 把对象序列化 JSON 字符串 /// </summary> /// <typeparam name="T">对象类型</typeparam> /// <param name="obj">对象实体</param> /// <returns>JSON字符串</returns> public static string GetJson<T>(T obj) { //记住 添加引用 System.ServiceModel.Web /** * 如果不添加上面的引用,System.Runtime.Serialization.Json; Json是出不来的哦 * */ DataContractJsonSerializer json = new DataContractJsonSerializer(typeof (T)); using (MemoryStream ms = new MemoryStream()) { json.WriteObject(ms, obj); string szJson = Encoding.UTF8.GetString(ms.ToArray()); return szJson; } } /// <summary> /// 把JSON字符串还原为对象 /// </summary> /// <typeparam name="T">对象类型</typeparam> /// <param name="szJson">JSON字符串</param> /// <returns>对象实体</returns> public static T ParseFormJson<T>(string szJson) { T obj = Activator.CreateInstance<T>(); using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(szJson))) { DataContractJsonSerializer dcj = new DataContractJsonSerializer(typeof (T)); return (T) dcj.ReadObject(ms); } } }
详细请看微信官方说明:
http://qydev.weixin.qq.com/wiki/index.php?title=WeixinJS%E6%8E%A5%E5%8F%A3
可以关注本人的公众号,多年经验的原创文章共享给大家。