• 微信授权步骤与详解 -- c#篇


    微信授权步骤与详解 -- 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

    可以关注本人的公众号,多年经验的原创文章共享给大家。

  • 相关阅读:
    线程同步之条件变量使用手记
    如何实现文件增量同步——算法
    javascript 复习笔记
    cocos2dx 多图层点击事件及管理相关问题记录
    cocos2dx 2.1.1 jsbinding 游戏帧数下降问题记录
    cocos2dx jsb + cocosbuilder 编译到安卓下问题处理(待续)
    cocos2dxjsb及Cocosbuilder使用相关问题处理记录
    cocos2dx jsb 的本地存储
    cocos2dxjsb 跨语言调用及第三方集成 过程记录
    cocos2dx 2.1.1 升级2.1.3版本 记录
  • 原文地址:https://www.cnblogs.com/alunchen/p/5282581.html
Copyright © 2020-2023  润新知