中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久

ASP.NET實現QQ、微信、新浪微博OAuth2.0授權登錄
來源:易賢網 閱讀:1660 次 日期:2016-08-10 15:52:20
溫馨提示:易賢網小編為您整理了“ASP.NET實現QQ、微信、新浪微博OAuth2.0授權登錄”,方便廣大網友查閱!

不管是騰訊還是新浪,查看他們的API,PHP都是有完整的接口,但對C#支持似乎都不是那么完善,都沒有,騰訊是完全沒有,新浪是提供第三方的,而且后期還不一定升級,NND,用第三方的動輒就一個類庫,各種配置還必須按照他們約定的寫,煩而且亂,索性自己寫,后期的擴展也容易,看過接口后,開始以為很難,參考了幾個源碼之后發現也不是那么難,無非是GET或POST請求他們的接口獲取返回值之類的,話不多說,這里只提供幾個代碼共參考,拋磚引玉了。

我這個寫法的特點是,用到了Session,使用對象實例化之后調用 Login() 跳轉到登錄頁面,在回調頁面調用Callback() 執行之后,可以從Session也可以寫獨立的函數(如:GetOpenID())中獲取access_token或用戶的唯一標識,以方便做下一步的操作。所謂綁定就是把用戶的唯一標識取出,插入數據庫,和帳號綁定起來。

1.首先是所有OAuth類的基類,放一些需要公用的方法

public abstract class BaseOAuth

{

  public HttpRequest Request = HttpContext.Current.Request;

  public HttpResponse Response = HttpContext.Current.Response;

  public HttpSessionState Session = HttpContext.Current.Session;

  public abstract void Login();

  public abstract string Callback();

  #region 內部使用函數

  /// <summary>

  /// 生成唯一隨機串防CSRF攻擊

  /// </summary>

  /// <returns></returns>

  protected string GetStateCode()

  {

    Random rand = new Random();

    string data = DateTime.Now.ToString("yyyyMMddHHmmssffff") + rand.Next(1, 0xf423f).ToString();

    MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();

    byte[] md5byte = md5.ComputeHash(UTF8Encoding.Default.GetBytes(data));

    return BitConverter.ToString(md5byte).Replace("-", "");

  }

  /// <summary>

  /// GET請求

  /// </summary>

  /// <param name="url"></param>

  /// <returns></returns>

  protected string GetRequest(string url)

  {

    HttpWebRequest httpWebRequest = System.Net.WebRequest.Create(url) as HttpWebRequest;

    httpWebRequest.Method = "GET";

    httpWebRequest.ServicePoint.Expect100Continue = false;

    StreamReader responseReader = null;

    string responseData;

    try

    {

      responseReader = new StreamReader(httpWebRequest.GetResponse().GetResponseStream());

      responseData = responseReader.ReadToEnd();

    }

    finally

    {

      httpWebRequest.GetResponse().GetResponseStream().Close();

      responseReader.Close();

    }

    return responseData;

  }

  /// <summary>

  /// POST請求

  /// </summary>

  /// <param name="url"></param>

  /// <param name="postData"></param>

  /// <returns></returns>

  protected string PostRequest(string url, string postData)

  {

    HttpWebRequest httpWebRequest = System.Net.WebRequest.Create(url) as HttpWebRequest;

    httpWebRequest.Method = "POST";

    httpWebRequest.ServicePoint.Expect100Continue = false;

    httpWebRequest.ContentType = "application/x-www-form-urlencoded";

    //寫入POST參數

    StreamWriter requestWriter = new StreamWriter(httpWebRequest.GetRequestStream());

    try

    {

      requestWriter.Write(postData);

    }

    finally

    {

      requestWriter.Close();

    }

    //讀取請求后的結果

    StreamReader responseReader = null;

    string responseData;

    try

    {

      responseReader = new StreamReader(httpWebRequest.GetResponse().GetResponseStream());

      responseData = responseReader.ReadToEnd();

    }

    finally

    {

      httpWebRequest.GetResponse().GetResponseStream().Close();

      responseReader.Close();

    }

    return responseData;

  }

  /// <summary>

  /// 解析JSON

  /// </summary>

  /// <param name="strJson"></param>

  /// <returns></returns>

  protected NameValueCollection ParseJson(string strJson)

  {

    NameValueCollection mc = new NameValueCollection();

    Regex regex = new Regex(@"(\s*\""?([^""]*)\""?\s*\:\s*\""?([^""]*)\""?\,?)");

    strJson = strJson.Trim();

    if (strJson.StartsWith("{"))

    {

      strJson = strJson.Substring(1, strJson.Length - 2);

    }

    foreach (Match m in regex.Matches(strJson))

    {

      mc.Add(m.Groups[2].Value, m.Groups[3].Value);

    }

    return mc;

  }

  /// <summary>

  /// 解析URL

  /// </summary>

  /// <param name="strParams"></param>

  /// <returns></returns>

  protected NameValueCollection ParseUrlParameters(string strParams)

  {

    NameValueCollection nc = new NameValueCollection();

    foreach (string p in strParams.Split('&'))

    {

      string[] ps = p.Split('=');

      nc.Add(ps[0], ps[1]);

    }

    return nc;

  }

  #endregion

}

2.QQ的OAuth類

public class QQOAuth : BaseOAuth

{

  public string AppId = ConfigurationManager.AppSettings["OAuth_QQ_AppId"];

  public string AppKey = ConfigurationManager.AppSettings["OAuth_QQ_AppKey"];

  public string RedirectUrl = ConfigurationManager.AppSettings["OAuth_QQ_RedirectUrl"];

  public const string GET_AUTH_CODE_URL = "https://graph.qq.com/oauth2.0/authorize";

  public const string GET_ACCESS_TOKEN_URL = "https://graph.qq.com/oauth2.0/token";

  public const string GET_OPENID_URL = "https://graph.qq.com/oauth2.0/me";

  /// <summary>

  /// QQ登錄,跳轉到登錄頁面

  /// </summary>

  public override void Login()

  {

    //-------生成唯一隨機串防CSRF攻擊

    string state = GetStateCode();

    Session["QC_State"] = state; //state 放入Session

    string parms = "?response_type=code&"

      + "client_id=" + AppId + "&redirect_uri=" + Uri.EscapeDataString(RedirectUrl) + "&state=" + state;

    string url = GET_AUTH_CODE_URL + parms;

    Response.Redirect(url); //跳轉到登錄頁面

  }

  /// <summary>

  /// QQ回調函數

  /// </summary>

  /// <param name="code"></param>

  /// <param name="state"></param>

  /// <returns></returns>

  public override string Callback()

  {

    string code = Request.QueryString["code"];

    string state = Request.QueryString["state"];

    //--------驗證state防止CSRF攻擊

    if (state != (string)Session["QC_State"])

    {

      ShowError("30001");

    }

    string parms = "?grant_type=authorization_code&"

      + "client_id=" + AppId + "&redirect_uri=" + Uri.EscapeDataString(RedirectUrl)

      + "&client_secret=" + AppKey + "&code=" + code;

    string url = GET_ACCESS_TOKEN_URL + parms;

    string str = GetRequest(url);

    if (str.IndexOf("callback") != -1)

    {

      int lpos = str.IndexOf("(");

      int rpos = str.IndexOf(")");

      str = str.Substring(lpos + 1, rpos - lpos - 1);

      NameValueCollection msg = ParseJson(str);

      if (!string.IsNullOrEmpty(msg["error"]))

      {

        ShowError(msg["error"], msg["error_description"]);

      }

    }

    NameValueCollection token = ParseUrlParameters(str);

    Session["QC_AccessToken"] = token["access_token"]; //access_token 放入Session

    return token["access_token"];

  }

  /// <summary>

  /// 使用Access Token來獲取用戶的OpenID

  /// </summary>

  /// <param name="accessToken"></param>

  /// <returns></returns>

  public string GetOpenID()

  {

    string parms = "?access_token=" + Session["QC_AccessToken"];

    string url = GET_OPENID_URL + parms;

    string str = GetRequest(url);

    if (str.IndexOf("callback") != -1)

    {

      int lpos = str.IndexOf("(");

      int rpos = str.IndexOf(")");

      str = str.Substring(lpos + 1, rpos - lpos - 1);

    }

    NameValueCollection user = ParseJson(str);

    if (!string.IsNullOrEmpty(user["error"]))

    {

      ShowError(user["error"], user["error_description"]);

    }

    Session["QC_OpenId"] = user["openid"]; //openid 放入Session

    return user["openid"];

  }

  /// <summary>

  /// 顯示錯誤信息

  /// </summary>

  /// <param name="code">錯誤編號</param>

  /// <param name="description">錯誤描述</param>

  private void ShowError(string code, string description = null)

  {

    if (description == null)

    {

      switch (code)

      {

        case "20001":

          description = "<h2>配置文件損壞或無法讀取,請檢查web.config</h2>";

          break;

        case "30001":

          description = "<h2>The state does not match. You may be a victim of CSRF.</h2>";

          break;

        case "50001":

          description = "<h2>可能是服務器無法請求https協議</h2>可能未開啟curl支持,請嘗試開啟curl支持,重啟web服務器,如果問題仍未解決,請聯系我們";

          break;

        default:

          description = "<h2>系統未知錯誤,請聯系我們</h2>";

          break;

      }

      Response.Write(description);

      Response.End();

    }

    else

    {

      Response.Write("<h3>error:<h3>" + code + "<h3>msg:<h3>" + description);

      Response.End();

    }

  }

}

3.新浪微博的OAuth類

public class SinaOAuth : BaseOAuth

{

  public string AppKey = ConfigurationManager.AppSettings["OAuth_Sina_AppKey"];

  public string AppSecret = ConfigurationManager.AppSettings["OAuth_Sina_AppSecret"];

  public string RedirectUrl = ConfigurationManager.AppSettings["OAuth_Sina_RedirectUrl"];

  public const string GET_AUTH_CODE_URL = "https://api.weibo.com/oauth2/authorize";

  public const string GET_ACCESS_TOKEN_URL = "https://api.weibo.com/oauth2/access_token";

  public const string GET_UID_URL = "https://api.weibo.com/2/account/get_uid.json";

  /// <summary>

  /// 新浪微博登錄,跳轉到登錄頁面

  /// </summary>

  public override void Login()

  {

    //-------生成唯一隨機串防CSRF攻擊

    string state = GetStateCode();

    Session["Sina_State"] = state; //state 放入Session

    string parms = "?client_id=" + AppKey + "&redirect_uri=" + Uri.EscapeDataString(RedirectUrl)

      + "&state=" + state;

    string url = GET_AUTH_CODE_URL + parms;

    Response.Redirect(url); //跳轉到登錄頁面

  }

  /// <summary>

  /// 新浪微博回調函數

  /// </summary>

  /// <returns></returns>

  public override string Callback()

  {

    string code = Request.QueryString["code"];

    string state = Request.QueryString["state"];

    //--------驗證state防止CSRF攻擊

    if (state != (string)Session["Sina_State"])

    {

      ShowError("The state does not match. You may be a victim of CSRF.");

    }

    string parms = "client_id=" + AppKey + "&client_secret=" + AppSecret

      + "&grant_type=authorization_code&code=" + code + "&redirect_uri=" + Uri.EscapeDataString(RedirectUrl);

    string str = PostRequest(GET_ACCESS_TOKEN_URL, parms);

    NameValueCollection user = ParseJson(str);

    Session["Sina_AccessToken"] = user["access_token"]; //access_token 放入Session

    Session["Sina_UId"] = user["uid"]; //uid 放入Session

    return user["access_token"];

  }

  /// <summary>

  /// 顯示錯誤信息

  /// </summary>

  /// <param name="description">錯誤描述</param>

  private void ShowError(string description = null)

  {

    Response.Write("<h2>" + description + "</h2>");

    Response.End();

  }

}

4.微信的OAuth類

public class WeixinOAuth : BaseOAuth

{

  public string AppId = ConfigurationManager.AppSettings["OAuth_Weixin_AppId"];

  public string AppSecret = ConfigurationManager.AppSettings["OAuth_Weixin_AppSecret"];

  public string RedirectUrl = ConfigurationManager.AppSettings["OAuth_Weixin_RedirectUrl"];

  public const string GET_AUTH_CODE_URL = "https://open.weixin.qq.com/connect/qrconnect";

  public const string GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token";

  public const string GET_USERINFO_URL = "https://api.weixin.qq.com/sns/userinfo";

  /// <summary>

  /// 微信登錄,跳轉到登錄頁面

  /// </summary>

  public override void Login()

  {

    //-------生成唯一隨機串防CSRF攻擊

    string state = GetStateCode();

    Session["Weixin_State"] = state; //state 放入Session

    string parms = "?appid=" + AppId

      + "&redirect_uri=" + Uri.EscapeDataString(RedirectUrl) + "&response_type=code&scope=snsapi_login"

      + "&state=" + state + "#wechat_redirect";

    string url = GET_AUTH_CODE_URL + parms;

    Response.Redirect(url); //跳轉到登錄頁面

  }

  /// <summary>

  /// 微信回調函數

  /// </summary>

  /// <param name="code"></param>

  /// <param name="state"></param>

  /// <returns></returns>

  public override string Callback()

  {

    string code = Request.QueryString["code"];

    string state = Request.QueryString["state"];

    //--------驗證state防止CSRF攻擊

    if (state != (string)Session["Weixin_State"])

    {

      ShowError("30001");

    }

    string parms = "?appid=" + AppId + "&secret=" + AppSecret

      + "&code=" + code + "&grant_type=authorization_code";

    string url = GET_ACCESS_TOKEN_URL + parms;

    string str = GetRequest(url);

    NameValueCollection msg = ParseJson(str);

    if (!string.IsNullOrEmpty(msg["errcode"]))

    {

      ShowError(msg["errcode"], msg["errmsg"]);

    }

    Session["Weixin_AccessToken"] = msg["access_token"]; //access_token 放入Session

    Session["Weixin_OpenId"] = msg["openid"]; //access_token 放入Session

    return msg["access_token"];

  }

  /// <summary>

  /// 顯示錯誤信息

  /// </summary>

  /// <param name="code">錯誤編號</param>

  /// <param name="description">錯誤描述</param>

  private void ShowError(string code, string description = null)

  {

    if (description == null)

    {

      switch (code)

      {

        case "20001":

          description = "<h2>配置文件損壞或無法讀取,請檢查web.config</h2>";

          break;

        case "30001":

          description = "<h2>The state does not match. You may be a victim of CSRF.</h2>";

          break;

        case "50001":

          description = "<h2>接口未授權</h2>";

          break;

        default:

          description = "<h2>系統未知錯誤,請聯系我們</h2>";

          break;

      }

      Response.Write(description);

      Response.End();

    }

    else

    {

      Response.Write("<h3>error:<h3>" + code + "<h3>msg:<h3>" + description);

      Response.End();

    }

  }

}

5.web.config配置信息

<appSettings>

    <!--QQ登錄相關配置-->

    <add key="OAuth_QQ_AppId" value="123456789" />

    <add key="OAuth_QQ_AppKey" value="25f9e794323b453885f5181f1b624d0b" />

    <add key="OAuth_QQ_RedirectUrl" value="http://www.domain.com/oauth20/qqcallback.aspx" />

    <!--新浪微博登錄相關配置-->

    <add key="OAuth_Sina_AppKey" value="123456789" />

    <add key="OAuth_Sina_AppSecret" value="25f9e794323b453885f5181f1b624d0b" />

    <add key="OAuth_Sina_RedirectUrl" value="http://www.domain.com/oauth20/sinacallback.aspx" />

    <!--微信登錄相關配置-->

    <add key="OAuth_Weixin_AppId" value="wx123456789123" />

    <add key="OAuth_Weixin_AppSecret" value="25f9e794323b453885f5181f1b624d0b" />

    <add key="OAuth_Weixin_RedirectUrl" value="http://www.domain.com/oauth20/weixincallback.aspx" />

</appSettings>

更多信息請查看網絡編程
由于各方面情況的不斷調整與變化,易賢網提供的所有考試信息和咨詢回復僅供參考,敬請考生以權威部門公布的正式信息和咨詢為準!

2026上岸·考公考編培訓報班

  • 報班類型
  • 姓名
  • 手機號
  • 驗證碼
關于我們 | 聯系我們 | 人才招聘 | 網站聲明 | 網站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點 | 投訴建議
工業和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網安備53010202001879號 人力資源服務許可證:(云)人服證字(2023)第0102001523號
云南網警備案專用圖標
聯系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關注公眾號:hfpxwx
咨詢QQ:1093837350(9:00—18:00)版權所有:易賢網
云南網警報警專用圖標
中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久
久久精品国产77777蜜臀| 欧美另类一区| 亚洲一区二区三区精品视频| 亚洲免费视频一区二区| 久久国产精品一区二区三区四区 | 久久精品一区二区三区中文字幕| 欧美在线视频一区二区| 老司机午夜精品视频在线观看| 米奇777在线欧美播放| 欧美日韩一区在线视频| 亚洲国产精品久久久久婷婷老年| 亚洲欧美日韩国产一区| 欧美激情精品久久久久久久变态| 国产精品久久久久免费a∨大胸| 黑人巨大精品欧美一区二区小视频| 亚洲区国产区| 免费在线观看精品| 国外成人在线视频网站| 亚洲欧美国产三级| 欧美性感一类影片在线播放| 亚洲看片免费| 欧美日韩国产bt| 亚洲精品一区在线观看| 老司机精品久久| 亚洲国产91| 欧美不卡视频一区发布| 亚洲欧洲在线视频| 欧美极品欧美精品欧美视频| 激情久久五月| 久久婷婷影院| 亚洲国产mv| 欧美美女视频| 午夜精品久久久久久久99黑人| 国产精品久久久久久久电影| 亚洲一区久久| 激情欧美一区| 欧美精品日韩一本| 亚洲一二区在线| 国产精品视频99| 美女免费视频一区| 一区二区三区黄色| 国产亚洲欧美一区二区| 欧美日韩成人综合| 久久精品视频免费播放| 亚洲精品日韩在线| 国产亚洲免费的视频看| 欧美黄色成人网| 久久精品中文字幕一区| 亚洲婷婷综合久久一本伊一区| 国产亚洲欧美日韩美女| 欧美肉体xxxx裸体137大胆| 美女视频黄免费的久久| 亚洲欧美日韩在线播放| 日韩视频在线观看| 极品少妇一区二区| 欧美午夜精品久久久久免费视| 久久欧美肥婆一二区| 亚洲欧美日韩一区在线| 亚洲精品资源美女情侣酒店| 亚洲高清成人| 影音先锋久久久| 尤物精品在线| 亚洲人成久久| 99精品欧美一区二区三区综合在线| 在线观看欧美视频| 精品动漫一区二区| 伊人成人在线视频| 伊人成人在线视频| 亚洲激情成人| 欧美一级网站| 另类图片综合电影| 欧美日本在线视频| 国产精品一级久久久| 国产一区亚洲一区| 亚洲精品欧洲精品| 欧美在线网站| 欧美日韩18| 国产一区二区激情| 亚洲欧洲精品一区二区精品久久久| 亚洲激情视频网| 亚洲欧美成人| 欧美激情一区二区三区全黄| 国产精品户外野外| 精品va天堂亚洲国产| 夜夜嗨av一区二区三区中文字幕| 在线综合+亚洲+欧美中文字幕| 午夜欧美精品久久久久久久| 欧美成人在线免费视频| 国产一区二区无遮挡| 91久久久久久| 亚洲欧美日韩国产中文| 欧美国产精品va在线观看| 国产欧美一区二区精品忘忧草 | 免播放器亚洲一区| 国产精品女主播一区二区三区| 一色屋精品亚洲香蕉网站| 亚洲一区影音先锋| 欧美日韩亚洲国产精品| 亚洲国产高清一区| 欧美在线视频观看| 国产精品第2页| 亚洲少妇一区| 欧美视频在线看| 99国产欧美久久久精品| 欧美1区2区视频| 亚洲高清123| 欧美国产日产韩国视频| 亚洲精品黄色| 欧美日韩一区成人| 夜夜嗨av一区二区三区网页| 欧美人妖在线观看| 一区二区三区精品在线| 欧美日韩国产限制| 亚洲综合电影一区二区三区| 国产精品亚洲网站| 欧美制服第一页| 国语自产精品视频在线看一大j8 | 国产精品视频精品| 久久国产主播精品| 亚洲全部视频| 欧美视频一区| 性欧美超级视频| 亚洲国产精品久久久久婷婷884| 久久久av毛片精品| 最新日韩在线视频| 国产精品第三页| 久久精品一区| 一本色道久久99精品综合 | 亚洲欧美日韩在线综合| 国产日产欧美a一级在线| 欧美va天堂在线| 亚洲午夜精品久久| 亚洲国产成人精品久久久国产成人一区| 久久久免费精品视频| 99re视频这里只有精品| 国产精品日韩专区| 欧美成人一区二区三区| 欧美一区二区三区免费观看| 亚洲欧美日韩一区| 欧美三区免费完整视频在线观看| 亚洲一区二区精品视频| 国内精品视频在线播放| 欧美午夜国产| 欧美电影打屁股sp| 久久成人在线| 久久久久久香蕉网| 欧美伊人久久| 久久九九99视频| 欧美一二区视频| 久久精品人人爽| 麻豆国产精品一区二区三区 | 99精品久久| 在线日本欧美| 在线成人中文字幕| 在线播放日韩专区| 伊人天天综合| 亚洲精品在线观看免费| 亚洲精品久久7777| 亚洲性视频网址| 亚洲女同精品视频| 久久精品国产亚洲高清剧情介绍| 久久精品视频在线看| 久久躁狠狠躁夜夜爽| 欧美成人精品一区二区| 欧美福利视频网站| 国产精品日韩在线播放| 韩国三级在线一区| 亚洲精品中文字幕女同| 午夜亚洲一区| 欧美日韩国产黄| 国产精品毛片a∨一区二区三区|国 | 欧美国产精品v| 国产精品美女久久久免费| 国产欧美一区二区三区久久| 亚洲国产精品悠悠久久琪琪| 亚洲一区二区三| 女仆av观看一区| 国产日韩欧美日韩大片| 最新日韩精品| 久久影院午夜论| 国产亚洲精品一区二区| 亚洲精品久久久久久久久久久久 | 韩日欧美一区二区三区| 99香蕉国产精品偷在线观看| 国产精品你懂得| 1769国产精品| 欧美午夜不卡视频| 久久人体大胆视频| 国产亚洲欧美一区二区| 亚洲午夜精品一区二区| 蜜臀久久久99精品久久久久久| 韩国av一区二区三区在线观看| 久久本道综合色狠狠五月| 国内成+人亚洲| 免费成人在线视频网站| 一本久久a久久精品亚洲| 欧美午夜在线视频| 一区二区三区高清| 一区久久精品| 国产日韩在线不卡|