搜尋
首頁微信小程式微信開發ASP.NET實作QQ、微信、新浪微博OAuth2.0授權登入的實例詳解

本文主要介紹了QQ、微信、新浪微博OAuth2.0授權登入的範例,主要是GET、POST遠端接口,傳回對應的數據,這裡列出相關的程式碼,供大家參考。

不管是騰訊還是新浪,查看他們的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(&#39;&&#39;))
    {
      string[] ps = p.Split(&#39;=&#39;);
      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 id="配置文件损坏或无法读取-请检查web-config">配置文件损坏或无法读取,请检查web.config</h2>";
          break;
        case "30001":
          description = "<h2 id="The-nbsp-state-nbsp-does-nbsp-not-nbsp-match-nbsp-You-nbsp-may-nbsp-be-nbsp-a-nbsp-victim-nbsp-of-nbsp-CSRF">The state does not match. You may be a victim of CSRF.</h2>";
          break;
        case "50001":
          description = "<h2 id="可能是服务器无法请求https协议">可能是服务器无法请求https协议</h2>可能未开启curl支持,请尝试开启curl支持,重启web服务器,如果问题仍未解决,请联系我们";
          break;
        default:
          description = "<h2 id="系统未知错误-请联系我们">系统未知错误,请联系我们</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 id="nbsp-nbsp-description-nbsp-nbsp">" + 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 id="配置文件损坏或无法读取-请检查web-config">配置文件损坏或无法读取,请检查web.config</h2>";
          break;
        case "30001":
          description = "<h2 id="The-nbsp-state-nbsp-does-nbsp-not-nbsp-match-nbsp-You-nbsp-may-nbsp-be-nbsp-a-nbsp-victim-nbsp-of-nbsp-CSRF">The state does not match. You may be a victim of CSRF.</h2>";
          break;
        case "50001":
          description = "<h2 id="接口未授权">接口未授权</h2>";
          break;
        default:
          description = "<h2 id="系统未知错误-请联系我们">系统未知错误,请联系我们</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>

以上是ASP.NET實作QQ、微信、新浪微博OAuth2.0授權登入的實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),