足球游戏_中国足彩网¥体育资讯$

ASP.NET实现QQ、微信、新浪微博OAuth2.0授权登录
来源:易贤网 阅读:1337 次 日期: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>

中国足彩网信息请查看网络编程
由于各方面情况的不断调整与变化,易贤网提供的所有考试信息和咨询回复仅供参考,敬请考生以权威部门公布的正式信息和咨询为准!

2025国考·省考课程试听报名

  • 报班类型
  • 姓名
  • 手机号
  • 验证码
关于我们 | 联系我们 | 人才招聘 | 网站声明 | 网站帮助 | 非正式的简要咨询 | 简要咨询须知 | 加入群交流 | 手机站点 | 投诉建议
工业和信息化部备案号:滇ICP备2023014141号-1 足球游戏_中国足彩网¥体育资讯$ 滇公网安备53010202001879号 人力资源服务许可证:(云)人服证字(2023)第0102001523号
云南网警备案专用图标
联系电话:0871-65099533/13759567129 获取招聘考试信息及咨询关注公众号:hfpxwx
咨询QQ:526150442(9:00—18:00)版权所有:易贤网
云南网警报警专用图标