C#第三方使用微信授權登錄


后面代碼需要用到的參數、方法、類

    private string WeChatRedirectUrl = "www.test.com";//需要被授權的頁面地址
    //對頁面進行授權重新返回的新地址,新地址包含code
    private string WeChatOauth2Url = @"https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type=code&scope=snsapi_userinfo&state=STATE#123";
    private string WeChatAccessTokenUrl = @"https://api.weixin.qq.com/sns/oauth2/access_token";//網頁授權access_token,獲取用戶唯一標識openID
    private string WeChatUserInfoUrl = @"https://api.weixin.qq.com/sns/userinfo";//獲取用戶信息地址
    private string WeChatAppId = "wx123456789abcdefg";//公眾號的唯一標識
    private string WeChatAppSecret = "a6d6ccf8182fn2a5a8e1ae1234e638c9";//公眾號的appsecret


    /// <summary>
    /// GET請求
    /// </summary>
    /// <param name="Url">The URL.</param>
    /// <param name="postDataStr">The post data string.</param>
    /// <returns>System.String.</returns>
    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;
    }

    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)
        {
            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);
            }
        }
    }

    //授權成功返回的信息
    public class OutWechatSuccessInfo
    {
        /// <summary>
        ///  code作為換取access_token的票據,每次用戶授權帶上的code將不一樣,code只能使用一次,5分鍾未被使用自動過期。
        /// </summary>
        public string code { get; set; }
        /// <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; }
    }

    //拉取的用戶信息
    public class OutWeChatUserInfo
    {
        /// <summary>
        ///  用戶的唯一標識
        /// </summary>
        public string openid { get; set; }
        /// <summary>
        /// 用戶昵稱
        /// </summary>
        public string nickname { get; set; }
        /// <summary>
        /// 用戶的性別,值為1時是男性,值為2時是女性,值為0時是未知
        /// </summary>
        public int sex { get; set; }
        /// <summary>
        /// 用戶個人資料填寫的省份
        /// </summary>
        public string province { get; set; }
        /// <summary>
        /// 普通用戶個人資料填寫的城市
        /// </summary>
        public string city { get; set; }
        /// <summary>
        /// 國家,如中國為CN
        /// </summary>
        public string country { get; set; }
        /// <summary>
        /// 用戶頭像,最后一個數值代表正方形頭像大小
        /// </summary>
        public string headimgurl { get; set; }
        /// <summary>
        /// 用戶特權信息
        /// </summary>
        public string privilege { get; set; }
    }

第一步:用戶同意授權,獲取code

    /// <summary>
    /// 獲取授權后的URL
    /// </summary>
    /// <returns></returns>
    public async Task<ReturnJson> GetRedirectUrl()
    {
        try
        {
            string url = string.Format(WeChatOauth2Url, WeChatAppId, WeChatRedirectUrl);
            return ReturnJson.ToResult(ReturnCode.Success, new { redirectURL = url });
        }
        catch (Exception e)
        {
            return ReturnJson.ToResult(ReturnCode.ServiceError, e.Message);
        }
    }

第二步:通過code換取網頁授權access_token和用戶唯一標識openID

    /// <summary>
    /// 獲取用戶唯一標識openID
    /// </summary>
    /// <param name="code"></param>
    /// <returns></returns>
    public OutWechatSuccessInfo GetOpenID(string code)
    {
        string sUrlpara = "appid=" + WeChatAppId + "&secret=" + WeChatAppSecret + "&code=" + code + "&grant_type=authorization_code";//請求的參數
        string jsonStr = HttpHelper.HttpGet(WeChatAccessTokenUrl, sUrlpara);

        if (jsonStr.Contains("errcode"))
        {
            return null;
        }

        //放回json解析
        OutWechatSuccessInfo result = new OutWechatSuccessInfo();
        result = JsonHelper.ParseFormJson<OutWechatSuccessInfo>(jsonStr);

        return result;
    }

第三步:拉取用戶信息(需scope為 snsapi_userinfo)

    /// <summary>
    /// 拉取登錄用戶信息
    /// </summary>
    /// <param name="accessToken"></param>
    /// <param name="openId"></param>
    /// <returns></returns>
    public OutWeChatUserInfo GetWeChatUserInfo(string accessToken, string openId)
    {
        string sUrlpara = "access_token=" + accessToken + "&openid=" + openId + "⟨=zh_CN"; ;//請求的參數
        string jsonStr = HttpHelper.HttpGet(WeChatUserInfoUrl, sUrlpara);

        if (jsonStr.Contains("errcode"))
        {
            return null;
        }

        //放回json解析
        OutWeChatUserInfo result = new OutWeChatUserInfo();
        result = JsonHelper.ParseFormJson<OutWeChatUserInfo>(jsonStr);

        return result;
    }

 補充:關於 return ReturnJson.ToResult ()這個是自己封裝的寫法,不一定要用我這個,只要能以json返回結果就行。ReturnJson.cs和EnumExtension.cs如下:

ReturnJson.cs引入命名空間:

using Common;

    public class ReturnJson
    {
        public ReturnJson()
        {
            Res = new Receive();
        }

        public static ReturnJson ToResult(ReturnCode code)
        {
            ReturnJson retJson = new ReturnJson
            {
                Code = ((int)code).ToString(),
                Res = new Receive
                {
                    Data = new { },
                    Msg = code.GetEnumText()
                }
            };
            return retJson;
        }

        public static ReturnJson ToResult(ReturnCode code, string msg, object data = null)
        {
            ReturnJson retJson = new ReturnJson
            {
                Code = ((int)code).ToString(),
                Res = new Receive
                {
                    Data = data ?? new { },
                    Msg = msg ?? code.GetEnumText()
                }
            };
            return retJson;
        }

        public static ReturnJson ToResult(ReturnCode code, object data)
        {
            ReturnJson retJson = new ReturnJson
            {
                Code = ((int)code).ToString(),
                Res = new Receive
                {
                    Data = data ?? new { },
                    Msg = code.GetEnumText()
                }
            };
            return retJson;
        }

        /// <summary>
        /// 調用返回值
        /// </summary>
        public string Code { get; set; }
        public Receive Res { get; set; }

    }

    public class Receive
    {
        public Receive()
        {
            Data = new { };
        }
        public string Msg { get; set; }

        public dynamic Data { get; set; }
    }

    /// <summary>
    /// 對外使用的返回值
    /// </summary>
    public enum ReturnCode
    {
        /// <summary>
        /// 請求(或處理)成功
        /// </summary>
        [Text("請求(或處理)成功")]
        Success = 0,
/// <summary> /// 參數錯誤 /// </summary> [Text("參數錯誤")] ParameterError = 409, /// <summary> /// 請求(或處理)失敗 /// </summary> [Text("請求(或處理)失敗")] Fault = 410,      /// <summary> /// 系統異常 /// </summary> [Text("系統異常")] SystemError = 500, /// <summary> /// 業務處理異常 /// </summary> [Text("業務處理異常")] ServiceError = 501, }

 

EnumExtension.cs引入命名空間:

using System;
using System.Collections.Generic;

    public static class EnumExtension
    {
        private static Dictionary<string, Dictionary<string, string>> _enumCache;

        private static Dictionary<string, Dictionary<string, string>> EnumCache => _enumCache ?? (_enumCache = new Dictionary<string, Dictionary<string, string>>());

        /// <summary>
        /// 返回枚舉的Text屬性值
        /// </summary>
        /// <param name="en">枚舉</param>
        /// <returns></returns>
        public static string GetEnumText(this Enum en)
        {
            string enString = string.Empty;
            if (null == en) return enString;
            var type = en.GetType();
            enString = en.ToString();
            if (!EnumCache.ContainsKey(type.FullName))
            {
                var fields = type.GetFields();
                Dictionary<string, string> temp = new Dictionary<string, string>();
                foreach (var item in fields)
                {
                    var attrs = item.GetCustomAttributes(typeof(TextAttribute), false);
                    if (attrs.Length == 1)
                    {
                        var v = ((TextAttribute)attrs[0]).Value;
                        temp.Add(item.Name, v);
                    }
                }
                EnumCache.Add(type.FullName, temp);
            }
            if (EnumCache[type.FullName].ContainsKey(enString))
            {
                return EnumCache[type.FullName][enString];
            }
            return enString;
        }

        /// <summary>
        /// 獲取枚舉的value值
        /// </summary>
        /// <param name="en">枚舉對象</param>
        /// <returns></returns>
        public static string ToIntString(this Enum en)
        {
            if (en == null)
                return "";
            var t = en.GetType();
            var field = t.GetField(en.ToString());
            var e = field.GetValue(en);
            return ((int)e).ToString();
        }

    }

    public class TextAttribute : Attribute
    {
        public TextAttribute(string value)
        {
            Value = value;
        }

        public string Value { get; set; }
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM